X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fnetwork.c;h=8eb8c1e557838aa7cfe1d81a6645a4bde334553d;hb=00b8c314dc2cfb641494d413f4b00d90a10ecbeb;hp=f7a9925a34f83ed6a82d1fc822c6e7b998d14c29;hpb=a079cfe6f815f8c69055de834d1ccbdf1fd94ba7;p=platform%2Fupstream%2Fconnman.git diff --git a/src/network.c b/src/network.c index f7a9925..8eb8c1e 100755 --- a/src/network.c +++ b/src/network.c @@ -27,6 +27,8 @@ #include #include "connman.h" +#include +#include "src/shared/arp.h" /* * How many times to send RS with the purpose of @@ -41,11 +43,6 @@ */ #define RS_REFRESH_TIMEOUT 3 -#if defined TIZEN_EXT -#define WIFI_ENCYPTION_MODE_LEN_MAX 6 -#define WIFI_BSSID_LEN_MAX 6 -#endif - /* * As per RFC 4861, a host should transmit up to MAX_RTR_SOLICITATIONS(3) * Router Solicitation messages, each separated by at least @@ -53,6 +50,14 @@ */ #define RTR_SOLICITATION_INTERVAL 4 +#define DHCP_RETRY_TIMEOUT 10 + +#if defined TIZEN_EXT +static unsigned char invalid_bssid[WIFI_BSSID_LEN_MAX] = { + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 +}; +#endif + static GSList *network_list = NULL; static GSList *driver_list = NULL; @@ -72,6 +77,9 @@ struct connman_network { int index; int router_solicit_count; int router_solicit_refresh_count; + struct acd_host *acd_host; + guint ipv4ll_timeout; + guint dhcp_timeout; struct connman_network_driver *driver; void *driver_data; @@ -90,26 +98,61 @@ struct connman_network { char *passphrase; char *eap; char *identity; + char *anonymous_identity; char *agent_identity; char *ca_cert_path; + char *subject_match; + char *altsubject_match; + char *domain_suffix_match; + char *domain_match; char *client_cert_path; char *private_key_path; char *private_key_passphrase; char *phase2_auth; bool wps; + bool wps_advertizing; bool use_wps; char *pin_wps; #if defined TIZEN_EXT char encryption_mode[WIFI_ENCYPTION_MODE_LEN_MAX]; unsigned char bssid[WIFI_BSSID_LEN_MAX]; unsigned int maxrate; + int maxspeed; bool isHS20AP; unsigned int keymgmt; char *keymgmt_type; bool rsn_mode; + bool pmf_required; int disconnect_reason; int assoc_status_code; GSList *vsie_list; + /* + * Only for EAP-FAST + */ + char *phase1; + unsigned char country_code[WIFI_COUNTRY_CODE_LEN]; + GSList *bssid_list; + GSList *sec_list; + ieee80211_modes_e phy_mode; + connection_mode_e connection_mode; + char *connector; + char *c_sign_key; + char *net_access_key; +#endif +#if defined TIZEN_EXT + unsigned char last_connected_bssid[WIFI_BSSID_LEN_MAX]; + GHashTable *assoc_reject_table; + bool owe_transition_mode; + void *transition_mode_ssid; + int transition_mode_ssid_len; + unsigned char transition_mode_bssid[WIFI_BSSID_LEN_MAX]; + bool roaming_progress; + bool roaming_dhcp; + char *roaming_cur_bssid; + char *roaming_dst_bssid; + __time_t roam_scan_time; + unsigned int max_bssid_count; + int snr; #endif } wifi; @@ -164,14 +207,270 @@ static void set_configuration(struct connman_network *network, __connman_device_set_network(network->device, network); - connman_device_set_disconnected(network->device, false); - service = connman_service_lookup_from_network(network); __connman_service_ipconfig_indicate_state(service, CONNMAN_SERVICE_STATE_CONFIGURATION, type); } +void connman_network_append_acddbus(DBusMessageIter *dict, + struct connman_network *network) +{ + if (!network->acd_host) + return; + + acd_host_append_dbus_property(network->acd_host, dict); +} + +static int start_acd(struct connman_network *network); + +static void remove_ipv4ll_timeout(struct connman_network *network) +{ + if (network->ipv4ll_timeout > 0) { + g_source_remove(network->ipv4ll_timeout); + network->ipv4ll_timeout = 0; + } +} + +static void acd_host_ipv4_available(struct acd_host *acd, gpointer user_data) +{ + struct connman_network *network = user_data; + struct connman_service *service; + struct connman_ipconfig *ipconfig_ipv4; + int err; + + if (!network) + return; + + service = connman_service_lookup_from_network(network); + if (!service) + return; + + ipconfig_ipv4 = __connman_service_get_ip4config(service); + if (!ipconfig_ipv4) { + connman_error("Service has no IPv4 configuration"); + return; + } + + err = __connman_ipconfig_address_add(ipconfig_ipv4); + if (err < 0) + goto err; + +#if defined TIZEN_EXT + err = __connman_ipconfig_gateway_add(ipconfig_ipv4, service); +#else + err = __connman_ipconfig_gateway_add(ipconfig_ipv4); +#endif + if (err < 0) + goto err; + + __connman_service_save(service); + + return; + +err: + connman_network_set_error(__connman_service_get_network(service), + CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); +} + +static int start_ipv4ll(struct connman_network *network) +{ + struct connman_service *service; + struct connman_ipconfig *ipconfig_ipv4; + struct in_addr addr; + char *address; + + service = connman_service_lookup_from_network(network); + if (!service) + return -EINVAL; + + ipconfig_ipv4 = __connman_service_get_ip4config(service); + if (!ipconfig_ipv4) { + connman_error("Service has no IPv4 configuration"); + return -EINVAL; + } + + /* Apply random IPv4 address. */ + addr.s_addr = htonl(arp_random_ip()); + address = inet_ntoa(addr); + if (!address) { + connman_error("Could not convert IPv4LL random address %u", + addr.s_addr); + return -EINVAL; + } + __connman_ipconfig_set_local(ipconfig_ipv4, address); + + connman_info("Probing IPv4LL address %s", address); + return start_acd(network); +} + +static gboolean start_ipv4ll_ontimeout(gpointer data) +{ + struct connman_network *network = data; + + if (!network) + return FALSE; + + /* Start IPv4LL ACD. */ + start_ipv4ll(network); + + return FALSE; +} + +static void acd_host_ipv4_lost(struct acd_host *acd, gpointer user_data) +{ + struct connman_network *network = user_data; + struct connman_service *service; + struct connman_ipconfig *ipconfig_ipv4; + enum connman_ipconfig_type type; + enum connman_ipconfig_method method; + + if (!network) + return; + + service = connman_service_lookup_from_network(network); + if (!service) + return; + + ipconfig_ipv4 = __connman_service_get_ip4config(service); + if (!ipconfig_ipv4) { + connman_error("Service has no IPv4 configuration"); + return; + } + + type = __connman_ipconfig_get_config_type(ipconfig_ipv4); + if (type != CONNMAN_IPCONFIG_TYPE_IPV4) + return; + + __connman_ipconfig_address_remove(ipconfig_ipv4); + + method = __connman_ipconfig_get_method(ipconfig_ipv4); + if (method == CONNMAN_IPCONFIG_METHOD_DHCP) { + /* + * We have one more chance for DHCP. If this fails + * acd_host_ipv4_conflict will be called. + */ + network = __connman_service_get_network(service); + if (network) + __connman_network_enable_ipconfig(network, ipconfig_ipv4); + } else { + /* Start IPv4LL ACD. */ + start_ipv4ll(network); + } +} + +static void acd_host_ipv4_conflict(struct acd_host *acd, gpointer user_data) +{ + struct connman_network *network = user_data; + struct connman_service *service; + struct connman_ipconfig *ipconfig_ipv4; + enum connman_ipconfig_method method; + + service = connman_service_lookup_from_network(network); + if (!service) + return; + + ipconfig_ipv4 = __connman_service_get_ip4config(service); + if (!ipconfig_ipv4) { + connman_error("Service has no IPv4 configuration"); + return; + } + + method = __connman_ipconfig_get_method(ipconfig_ipv4); + connman_info("%s conflict counts=%u", __FUNCTION__, + acd_host_get_conflicts_count(acd)); + + if (method == CONNMAN_IPCONFIG_METHOD_DHCP && + acd_host_get_conflicts_count(acd) < 2) { + connman_info("%s Sending DHCP decline", __FUNCTION__); + __connman_dhcp_decline(ipconfig_ipv4); + + connman_network_set_connected_dhcp_later(network, DHCP_RETRY_TIMEOUT); + __connman_ipconfig_set_local(ipconfig_ipv4, NULL); + } else { + if (method == CONNMAN_IPCONFIG_METHOD_DHCP) { + __connman_ipconfig_set_method(ipconfig_ipv4, + CONNMAN_IPCONFIG_METHOD_AUTO); + __connman_dhcp_decline(ipconfig_ipv4); + } + /* Start IPv4LL ACD. */ + start_ipv4ll(network); + } +} + +static void acd_host_ipv4_maxconflict(struct acd_host *acd, gpointer user_data) +{ + struct connman_network *network = user_data; + + remove_ipv4ll_timeout(network); + connman_info("Had maximum number of conflicts. Next IPv4LL address will be " + "tried in %d seconds", RATE_LIMIT_INTERVAL); + /* Wait, then start IPv4LL ACD. */ + network->ipv4ll_timeout = + g_timeout_add_seconds_full(G_PRIORITY_HIGH, + RATE_LIMIT_INTERVAL, + start_ipv4ll_ontimeout, + network, + NULL); +} + +static int start_acd(struct connman_network *network) +{ + struct connman_service *service; + struct connman_ipconfig *ipconfig_ipv4; + const char* address; + struct in_addr addr; + + remove_ipv4ll_timeout(network); + + service = connman_service_lookup_from_network(network); + if (!service) + return -EINVAL; + + ipconfig_ipv4 = __connman_service_get_ip4config(service); + if (!ipconfig_ipv4) { + connman_error("Service has no IPv4 configuration"); + return -EINVAL; + } + + if (!network->acd_host) { + int index; + + index = __connman_ipconfig_get_index(ipconfig_ipv4); + network->acd_host = acd_host_new(index, + connman_service_get_dbuspath(service)); + if (!network->acd_host) { + connman_error("Could not create ACD data structure"); + return -EINVAL; + } + + acd_host_register_event(network->acd_host, + ACD_HOST_EVENT_IPV4_AVAILABLE, + acd_host_ipv4_available, network); + acd_host_register_event(network->acd_host, + ACD_HOST_EVENT_IPV4_LOST, + acd_host_ipv4_lost, network); + acd_host_register_event(network->acd_host, + ACD_HOST_EVENT_IPV4_CONFLICT, + acd_host_ipv4_conflict, network); + acd_host_register_event(network->acd_host, + ACD_HOST_EVENT_IPV4_MAXCONFLICT, + acd_host_ipv4_maxconflict, network); + } + + address = __connman_ipconfig_get_local(ipconfig_ipv4); + if (!address) + return -EINVAL; + + connman_info("Starting ACD for address %s", address); + if (inet_pton(AF_INET, address, &addr) != 1) + connman_error("Could not convert address %s", address); + + acd_host_start(network->acd_host, htonl(addr.s_addr)); + + return 0; +} + static void dhcp_success(struct connman_network *network) { struct connman_service *service; @@ -189,6 +488,14 @@ static void dhcp_success(struct connman_network *network) if (!ipconfig_ipv4) return; + if (connman_setting_get_bool("AddressConflictDetection")) { + err = start_acd(network); + if (!err) + return; + + /* On error proceed without ACD. */ + } + err = __connman_ipconfig_address_add(ipconfig_ipv4); if (err < 0) goto err; @@ -201,6 +508,8 @@ static void dhcp_success(struct connman_network *network) if (err < 0) goto err; + __connman_service_save(service); + return; err: @@ -251,12 +560,24 @@ static int set_connected_manual(struct connman_network *network) network->connecting = false; service = connman_service_lookup_from_network(network); - ipconfig = __connman_service_get_ip4config(service); + __connman_ipconfig_enable(ipconfig); +#if defined TIZEN_EXT + if (!service || !ipconfig) + return -EINVAL; +#endif if (!__connman_ipconfig_get_local(ipconfig)) __connman_service_read_ip4config(service); + if (connman_setting_get_bool("AddressConflictDetection")) { + err = start_acd(network); + if (!err) + return 0; + + /* On error proceed without ACD. */ + } + err = __connman_ipconfig_address_add(ipconfig); if (err < 0) goto err; @@ -273,16 +594,30 @@ err: return err; } +static void remove_dhcp_timeout(struct connman_network *network) +{ + if (network->dhcp_timeout > 0) { + g_source_remove(network->dhcp_timeout); + network->dhcp_timeout = 0; + } +} + +#if defined TIZEN_EXT +int set_connected_dhcp(struct connman_network *network) +#else static int set_connected_dhcp(struct connman_network *network) +#endif { struct connman_service *service; struct connman_ipconfig *ipconfig_ipv4; int err; DBG("network %p", network); + remove_dhcp_timeout(network); service = connman_service_lookup_from_network(network); ipconfig_ipv4 = __connman_service_get_ip4config(service); + __connman_ipconfig_enable(ipconfig_ipv4); err = __connman_dhcp_start(ipconfig_ipv4, network, dhcp_callback, NULL); @@ -294,6 +629,44 @@ static int set_connected_dhcp(struct connman_network *network) return 0; } +static gboolean set_connected_dhcp_timout(gpointer data) +{ + struct connman_network *network = data; + struct connman_service *service; + struct connman_ipconfig *ipconfig; + enum connman_ipconfig_method method; + + network->dhcp_timeout = 0; + + service = connman_service_lookup_from_network(network); + if (!service) + return FALSE; + + ipconfig = __connman_service_get_ip4config(service); + if (!ipconfig) + return FALSE; + + /* Method is still DHCP? */ + method = __connman_ipconfig_get_method(ipconfig); + if (method == CONNMAN_IPCONFIG_METHOD_DHCP) + set_connected_dhcp(network); + + return FALSE; +} + +void connman_network_set_connected_dhcp_later(struct connman_network *network, + uint32_t sec) +{ + remove_dhcp_timeout(network); + + network->dhcp_timeout = + g_timeout_add_seconds_full(G_PRIORITY_HIGH, + sec, + set_connected_dhcp_timout, + network, + NULL); +} + static int manual_ipv6_set(struct connman_network *network, struct connman_ipconfig *ipconfig_ipv6) { @@ -326,13 +699,8 @@ static int manual_ipv6_set(struct connman_network *network, if (err < 0) return err; - __connman_connection_gateway_activate(service, - CONNMAN_IPCONFIG_TYPE_IPV6); - __connman_device_set_network(network->device, network); - connman_device_set_disconnected(network->device, false); - connman_network_set_associating(network, false); network->connecting = false; @@ -384,6 +752,10 @@ static int dhcpv6_set_addresses(struct connman_network *network) network->connecting = false; ipconfig_ipv6 = __connman_service_get_ip6config(service); +#if defined TIZEN_EXT + if (!ipconfig_ipv6) + goto err; +#endif err = __connman_ipconfig_address_add(ipconfig_ipv6); if (err < 0) goto err; @@ -568,7 +940,6 @@ static void receive_refresh_rs_reply(struct nd_router_advert *reply, network->router_solicit_refresh_count = 0; connman_network_unref(network); - return; } int __connman_network_refresh_rs_ipv6(struct connman_network *network, @@ -613,8 +984,6 @@ static void autoconf_ipv6_set(struct connman_network *network) __connman_device_set_network(network->device, network); - connman_device_set_disconnected(network->device, false); - #if defined TIZEN_EXT if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR) return; @@ -628,6 +997,8 @@ static void autoconf_ipv6_set(struct connman_network *network) if (!ipconfig) return; + __connman_ipconfig_enable(ipconfig); + __connman_ipconfig_enable_ipv6(ipconfig); __connman_ipconfig_address_remove(ipconfig); @@ -710,11 +1081,22 @@ static void set_disconnected(struct connman_network *network) switch (ipv4_method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_AUTO: case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: break; + case CONNMAN_IPCONFIG_METHOD_AUTO: + /* + * If the current method is AUTO then next time we + * try first DHCP. DHCP also needs to be stopped + * in this case because if we fell in AUTO means + * that DHCP was launched for IPv4 but it failed. + */ + __connman_ipconfig_set_method(ipconfig_ipv4, + CONNMAN_IPCONFIG_METHOD_DHCP); + __connman_service_notify_ipv4_configuration(service); + /* fall through */ case CONNMAN_IPCONFIG_METHOD_DHCP: + remove_dhcp_timeout(network); __connman_dhcp_stop(ipconfig_ipv4); break; } @@ -755,6 +1137,7 @@ static void set_disconnected(struct connman_network *network) __connman_ipconfig_address_unset(ipconfig_ipv4); __connman_ipconfig_address_unset(ipconfig_ipv6); + #if defined TIZEN_EXT } #endif @@ -803,7 +1186,9 @@ static int network_probe(struct connman_network *network) driver = NULL; continue; } - +#if defined TIZEN_EXT + if (!simplified_log) +#endif DBG("driver %p name %s", driver, driver->name); if (driver->probe(network) == 0) @@ -895,20 +1280,6 @@ static void probe_driver(struct connman_network_driver *driver) } } -static void remove_driver(struct connman_network_driver *driver) -{ - GSList *list; - - DBG("driver %p name %s", driver, driver->name); - - for (list = network_list; list; list = list->next) { - struct connman_network *network = list->data; - - if (network->driver == driver) - network_remove(network); - } -} - static gint compare_priority(gconstpointer a, gconstpointer b) { const struct connman_network_driver *driver1 = a; @@ -945,11 +1316,18 @@ int connman_network_driver_register(struct connman_network_driver *driver) */ void connman_network_driver_unregister(struct connman_network_driver *driver) { + GSList *list; + DBG("driver %p name %s", driver, driver->name); driver_list = g_slist_remove(driver_list, driver); - remove_driver(driver); + for (list = network_list; list; list = list->next) { + struct connman_network *network = list->data; + + if (network->driver == driver) + network_remove(network); + } } static void network_destruct(struct connman_network *network) @@ -962,21 +1340,30 @@ static void network_destruct(struct connman_network *network) g_free(network->wifi.passphrase); g_free(network->wifi.eap); g_free(network->wifi.identity); + g_free(network->wifi.anonymous_identity); g_free(network->wifi.agent_identity); g_free(network->wifi.ca_cert_path); + g_free(network->wifi.subject_match); + g_free(network->wifi.altsubject_match); + g_free(network->wifi.domain_suffix_match); + g_free(network->wifi.domain_match); g_free(network->wifi.client_cert_path); g_free(network->wifi.private_key_path); g_free(network->wifi.private_key_passphrase); g_free(network->wifi.phase2_auth); g_free(network->wifi.pin_wps); + #if defined TIZEN_EXT g_slist_free_full(network->wifi.vsie_list, g_free); + g_slist_free_full(network->wifi.bssid_list, g_free); + g_hash_table_destroy(network->wifi.assoc_reject_table); #endif g_free(network->path); g_free(network->group); g_free(network->node); g_free(network->name); g_free(network->identifier); + acd_host_free(network->acd_host); network->device = NULL; @@ -985,7 +1372,7 @@ static void network_destruct(struct connman_network *network) /** * connman_network_create: - * @identifier: network identifier (for example an unqiue name) + * @identifier: network identifier (for example an unique name) * * Allocate a new network and assign the #identifier to it. * @@ -997,14 +1384,10 @@ struct connman_network *connman_network_create(const char *identifier, struct connman_network *network; char *ident; - DBG("identifier %s type %d", identifier, type); - network = g_try_new0(struct connman_network, 1); if (!network) return NULL; - DBG("network %p", network); - network->refcount = 1; ident = g_strdup(identifier); @@ -1016,9 +1399,15 @@ struct connman_network *connman_network_create(const char *identifier, network->type = type; network->identifier = ident; + network->acd_host = NULL; + network->ipv4ll_timeout = 0; network_list = g_slist_prepend(network_list, network); + network->dhcp_timeout = 0; + + DBG("network %p identifier %s type %s", network, identifier, + type2string(type)); return network; } @@ -1032,6 +1421,9 @@ struct connman_network * connman_network_ref_debug(struct connman_network *network, const char *file, int line, const char *caller) { +#if defined TIZEN_EXT + if (!simplified_log) +#endif DBG("%p name %s ref %d by %s:%d:%s()", network, network->name, network->refcount + 1, file, line, caller); @@ -1049,6 +1441,9 @@ connman_network_ref_debug(struct connman_network *network, void connman_network_unref_debug(struct connman_network *network, const char *file, int line, const char *caller) { +#if defined TIZEN_EXT + if (!simplified_log) +#endif DBG("%p name %s ref %d by %s:%d:%s()", network, network->name, network->refcount - 1, file, line, caller); @@ -1369,6 +1764,13 @@ static gboolean __connman_network_clear_associating_delayed(gpointer user_data) } #endif +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET +bool connman_network_check_validity(struct connman_network *network) +{ + return (NULL == g_slist_find(network_list, network)) ? false : true; +} +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + /** * connman_network_set_associating: * @network: network structure @@ -1409,6 +1811,22 @@ int connman_network_set_associating(struct connman_network *network, return 0; } +#if defined TIZEN_EXT +static void set_authenticate_error(struct connman_network *network) +{ + struct connman_service *service; + + service = connman_service_lookup_from_network(network); + + if (!service) + return; + + __connman_service_indicate_error(service, + CONNMAN_SERVICE_ERROR_AUTH_FAILED); +} +#endif + + static void set_associate_error(struct connman_network *network) { struct connman_service *service; @@ -1416,8 +1834,11 @@ static void set_associate_error(struct connman_network *network) service = connman_service_lookup_from_network(network); #if defined TIZEN_EXT + if (!service) + return; + __connman_service_indicate_error(service, - CONNMAN_SERVICE_ERROR_AUTH_FAILED); + CONNMAN_SERVICE_ERROR_ASSOC_FAILED); #else __connman_service_indicate_error(service, CONNMAN_SERVICE_ERROR_CONNECT_FAILED); @@ -1539,6 +1960,9 @@ void connman_network_set_error(struct connman_network *network, set_connect_error(network); break; #if defined TIZEN_EXT + case CONNMAN_NETWORK_ERROR_AUTHENTICATE_FAIL: + set_authenticate_error(network); + break; case CONNMAN_NETWORK_ERROR_DHCP_FAIL: set_dhcp_error(network); break; @@ -1547,7 +1971,6 @@ void connman_network_set_error(struct connman_network *network, case CONNMAN_NETWORK_ERROR_BLOCKED: set_blocked_error(network); break; - } __connman_network_disconnect(network); @@ -1685,15 +2108,17 @@ int __connman_network_connect(struct connman_network *network) if (!network->device) return -ENODEV; - network->connecting = true; - #if defined TIZEN_EXT if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR) #endif __connman_device_disconnect(network->device); + + network->connecting = true; + #if defined TIZEN_EXT DBG("ConnMan, Connect Request [%s]", network->name); #endif + err = network->driver->connect(network); if (err < 0) { if (err == -EINPROGRESS) { @@ -1707,6 +2132,18 @@ int __connman_network_connect(struct connman_network *network) return err; } +#if defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET + /* + * Note: If EAP on Ethernet is ON, then network will be connected + * after EAP Success event is recieved, from plugin/ethernet.c + */ + struct connman_service *service = connman_service_lookup_from_network(network); + if (service && __connman_service_get_use_eapol(service)) { + connman_network_set_associating(network, true); + return 0; + } +#endif /* defined TIZEN_EXT && defined TIZEN_EXT_EAP_ON_ETHERNET */ + set_connected(network); return err; @@ -1721,9 +2158,15 @@ int __connman_network_connect(struct connman_network *network) int __connman_network_disconnect(struct connman_network *network) { int err = 0; - +#if defined TIZEN_EXT + if (!simplified_log) +#endif DBG("network %p", network); + remove_ipv4ll_timeout(network); + if (network->acd_host) + acd_host_stop(network->acd_host); + if (!network->connected && !network->connecting && !network->associating) return -ENOTCONN; @@ -1732,8 +2175,11 @@ int __connman_network_disconnect(struct connman_network *network) return -EUNATCH; network->connecting = false; + #if defined TIZEN_EXT DBG("ConnMan, Disconnect request"); + struct connman_service *service = connman_service_lookup_from_network(network); + connman_service_set_disconnection_requested(service, true); #endif if (network->driver->disconnect) err = network->driver->disconnect(network); @@ -1765,13 +2211,16 @@ int __connman_network_clear_ipconfig(struct connman_network *network, case CONNMAN_IPCONFIG_METHOD_OFF: case CONNMAN_IPCONFIG_METHOD_FIXED: return -EINVAL; - case CONNMAN_IPCONFIG_METHOD_AUTO: - release_dhcpv6(network); - break; case CONNMAN_IPCONFIG_METHOD_MANUAL: __connman_ipconfig_address_remove(ipconfig); break; + case CONNMAN_IPCONFIG_METHOD_AUTO: + release_dhcpv6(network); + if (type == CONNMAN_IPCONFIG_TYPE_IPV6) + break; + /* fall through */ case CONNMAN_IPCONFIG_METHOD_DHCP: + remove_dhcp_timeout(network); __connman_dhcp_stop(ipconfig_ipv4); break; } @@ -1943,9 +2392,10 @@ int connman_network_set_bssid(struct connman_network *network, if (bssid == NULL) return -EINVAL; - DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network, - bssid[0], bssid[1], bssid[2], - bssid[3], bssid[4], bssid[5]); + if (!simplified_log) + DBG("network %p bssid %02x:%02x:%02x:%02x:%02x:%02x", network, + bssid[0], bssid[1], bssid[2], + bssid[3], bssid[4], bssid[5]); for (;i < WIFI_BSSID_LEN_MAX;i++) network->wifi.bssid[i] = bssid[i]; @@ -1958,6 +2408,73 @@ unsigned char *connman_network_get_bssid(struct connman_network *network) return (unsigned char *)network->wifi.bssid; } +int connman_network_set_transition_mode_bssid(struct connman_network *network, + const unsigned char *transition_mode_bssid) +{ + int i = 0; + + if (transition_mode_bssid == NULL) + return -EINVAL; + + for (;i < WIFI_BSSID_LEN_MAX;i++) + network->wifi.transition_mode_bssid[i] = transition_mode_bssid[i]; + + return 0; +} + +unsigned char *connman_network_get_transition_mode_bssid(struct connman_network *network) +{ + return (unsigned char *)network->wifi.transition_mode_bssid; +} + +bool connman_network_check_transition_mode(struct connman_network *network1, struct connman_network *network2) +{ + + if (network1 == NULL || network2 == NULL) + return FALSE; + + if (network1->wifi.owe_transition_mode == FALSE || network2->wifi.owe_transition_mode == FALSE) + return FALSE; + + if ((memcmp(network1->wifi.bssid, network2->wifi.transition_mode_bssid, WIFI_BSSID_LEN_MAX) == 0) + && (memcmp(network1->wifi.transition_mode_bssid, network2->wifi.bssid, WIFI_BSSID_LEN_MAX) == 0)) + return TRUE; + else + return FALSE; +} + +int connman_network_set_maxspeed(struct connman_network *network, + int maxspeed) +{ + network->wifi.maxspeed = maxspeed; + return 0; +} + +int connman_network_get_maxspeed(struct connman_network *network) +{ + if (!network->driver) + return 0; + + if (network->connected) + return network->wifi.maxspeed; + + return 0; +} + +int connman_network_set_sec_list(struct connman_network *network, + GSList *sec_list) +{ + g_slist_free(network->wifi.sec_list); + network->wifi.sec_list = sec_list; + + return 0; +} + +void *connman_network_get_sec_list(struct connman_network *network) +{ + return network->wifi.sec_list; +} + int connman_network_set_maxrate(struct connman_network *network, unsigned int maxrate) { @@ -1981,7 +2498,8 @@ int connman_network_set_enc_mode(struct connman_network *network, if (encryption_mode == NULL) return -EINVAL; - DBG("network %p encryption mode %s", network, encryption_mode); + if (!simplified_log) + DBG("network %p encryption mode %s", network, encryption_mode); g_strlcpy(network->wifi.encryption_mode, encryption_mode, WIFI_ENCYPTION_MODE_LEN_MAX); @@ -2058,26 +2576,152 @@ int connman_network_get_disconnect_reason(struct connman_network *network) return network->wifi.disconnect_reason; } - -int connman_network_set_assoc_status_code(struct connman_network *network, - int assoc_status_code) +int connman_network_get_assoc_status_code(struct connman_network *network) { - if (network == NULL) return 0; - network->wifi.assoc_status_code = assoc_status_code; + return network->wifi.assoc_status_code; +} + +int connman_network_set_countrycode(struct connman_network *network, + const unsigned char *country_code) +{ + int i = 0; + + if (country_code == NULL) + return -EINVAL; + + if (!simplified_log) + DBG("network %p Country Code %02x:%02x",network, + country_code[0],country_code[1]); + + for (; i < WIFI_COUNTRY_CODE_LEN; i++) + network->wifi.country_code[i] = country_code[i]; + return 0; } -int connman_network_get_assoc_status_code(struct connman_network *network) +unsigned char *connman_network_get_countrycode(struct connman_network *network) { - if (network == NULL) - return 0; + return (unsigned char *)network->wifi.country_code; +} - return network->wifi.assoc_status_code; +int connman_network_set_bssid_list(struct connman_network *network, + GSList *bssids) +{ + unsigned int max_bssid_count; + + g_slist_free_full(network->wifi.bssid_list, g_free); + network->wifi.bssid_list = bssids; + + max_bssid_count = g_slist_length(bssids); + if (network->wifi.max_bssid_count < max_bssid_count) + network->wifi.max_bssid_count = max_bssid_count; + + return 0; +} + +int connman_network_set_phy_mode(struct connman_network *network, + ieee80211_modes_e mode) +{ + if (!simplified_log) + DBG("network %p phy mode %d", network, mode); + network->wifi.phy_mode = mode; + + return 0; +} + +ieee80211_modes_e connman_network_get_phy_mode(struct connman_network *network) +{ + return network->wifi.phy_mode; +} + +int connman_network_set_connection_mode(struct connman_network *network, + connection_mode_e mode) +{ + DBG("network %p connection mode %d", network, mode); + network->wifi.connection_mode = mode; + + return 0; +} + +connection_mode_e connman_network_get_connection_mode(struct connman_network *network) +{ + return network->wifi.connection_mode; +} + +void *connman_network_get_bssid_list(struct connman_network *network) +{ + return network->wifi.bssid_list; +} + +unsigned int connman_network_get_max_bssid_count(struct connman_network *network) +{ + return network->wifi.max_bssid_count; +} + +int connman_network_set_last_connected_bssid(struct connman_network *network, + const unsigned char *bssid) +{ + if (!bssid) + return -EINVAL; + + if (!memcmp(bssid, invalid_bssid, WIFI_BSSID_LEN_MAX)) + return -EINVAL; + + memcpy(network->wifi.last_connected_bssid, bssid, WIFI_BSSID_LEN_MAX); + + return 0; +} + +unsigned char *connman_network_get_last_connected_bssid(struct connman_network *network) +{ + return (unsigned char *)network->wifi.last_connected_bssid; +} + +void connman_network_set_assoc_reject_table(struct connman_network *network, + GHashTable *assoc_reject_table) +{ + if (!network) + return; + + if (!assoc_reject_table) + return; + + g_hash_table_destroy(network->wifi.assoc_reject_table); + + network->wifi.assoc_reject_table = assoc_reject_table; +} + +GHashTable *connman_network_get_assoc_reject_table(struct connman_network *network) +{ + if (!network) + return NULL; + + return network->wifi.assoc_reject_table; } +__time_t connman_network_get_roam_scan_time(struct connman_network *network) +{ + return network->wifi.roam_scan_time; +} + +void connman_network_set_roam_scan_time(struct connman_network *network, + __time_t roam_scan_time) +{ + network->wifi.roam_scan_time = roam_scan_time; +} + +int connman_network_get_snr(struct connman_network *network) +{ + return network->wifi.snr; +} + +void connman_network_set_snr(struct connman_network *network, int snr) +{ + network->wifi.snr = snr; +} #endif int connman_network_set_nameservers(struct connman_network *network, @@ -2142,6 +2786,9 @@ int connman_network_set_domain(struct connman_network *network, int connman_network_set_name(struct connman_network *network, const char *name) { +#if defined TIZEN_EXT + if (!simplified_log) +#endif DBG("network %p name %s", network, name); g_free(network->name); @@ -2161,11 +2808,10 @@ int connman_network_set_name(struct connman_network *network, int connman_network_set_strength(struct connman_network *network, uint8_t strength) { -#if !defined TIZEN_EXT - DBG("network %p strengh %d", network, strength); -#endif - network->strength = strength; +#if defined TIZEN_EXT + __connman_service_notify_strength_changed(network); +#endif return 0; } @@ -2178,10 +2824,6 @@ uint8_t connman_network_get_strength(struct connman_network *network) int connman_network_set_frequency(struct connman_network *network, uint16_t frequency) { -#if !defined TIZEN_EXT - DBG("network %p frequency %d", network, frequency); -#endif - network->frequency = frequency; return 0; @@ -2195,13 +2837,26 @@ uint16_t connman_network_get_frequency(struct connman_network *network) int connman_network_set_wifi_channel(struct connman_network *network, uint16_t channel) { - DBG("network %p wifi channel %d", network, channel); - network->wifi.channel = channel; return 0; } +int connman_network_set_autoconnect(struct connman_network *network, + bool autoconnect) +{ + if (!network->driver || !network->driver->set_autoconnect) + return 0; + return network->driver->set_autoconnect(network, autoconnect); +} + +bool __connman_network_native_autoconnect(struct connman_network *network) +{ + if (!network->driver || !network->driver->set_autoconnect) + return false; + return true; +} + uint16_t connman_network_get_wifi_channel(struct connman_network *network) { return network->wifi.channel; @@ -2218,10 +2873,6 @@ uint16_t connman_network_get_wifi_channel(struct connman_network *network) int connman_network_set_string(struct connman_network *network, const char *key, const char *value) { -#if !defined TIZEN_EXT - DBG("network %p key %s value %s", network, key, value); -#endif - if (g_strcmp0(key, "Name") == 0) return connman_network_set_name(network, value); @@ -2249,12 +2900,27 @@ int connman_network_set_string(struct connman_network *network, } else if (g_str_equal(key, "WiFi.Identity")) { g_free(network->wifi.identity); network->wifi.identity = g_strdup(value); + } else if (g_str_equal(key, "WiFi.AnonymousIdentity")) { + g_free(network->wifi.anonymous_identity); + network->wifi.anonymous_identity = g_strdup(value); } else if (g_str_equal(key, "WiFi.AgentIdentity")) { g_free(network->wifi.agent_identity); network->wifi.agent_identity = g_strdup(value); } else if (g_str_equal(key, "WiFi.CACertFile")) { g_free(network->wifi.ca_cert_path); network->wifi.ca_cert_path = g_strdup(value); + } else if (g_str_equal(key, "WiFi.SubjectMatch")) { + g_free(network->wifi.subject_match); + network->wifi.subject_match = g_strdup(value); + } else if (g_str_equal(key, "WiFi.AltSubjectMatch")) { + g_free(network->wifi.altsubject_match); + network->wifi.altsubject_match = g_strdup(value); + } else if (g_str_equal(key, "WiFi.DomainSuffixMatch")) { + g_free(network->wifi.domain_suffix_match); + network->wifi.domain_suffix_match = g_strdup(value); + } else if (g_str_equal(key, "WiFi.DomainMatch")) { + g_free(network->wifi.domain_match); + network->wifi.domain_match = g_strdup(value); } else if (g_str_equal(key, "WiFi.ClientCertFile")) { g_free(network->wifi.client_cert_path); network->wifi.client_cert_path = g_strdup(value); @@ -2270,6 +2936,23 @@ int connman_network_set_string(struct connman_network *network, } else if (g_str_equal(key, "WiFi.PinWPS")) { g_free(network->wifi.pin_wps); network->wifi.pin_wps = g_strdup(value); +#if defined TIZEN_EXT + } else if (g_str_equal(key, "WiFi.Connector")) { + g_free(network->wifi.connector); + network->wifi.connector = g_strdup(value); + } else if (g_str_equal(key, "WiFi.CSignKey")) { + g_free(network->wifi.c_sign_key); + network->wifi.c_sign_key = g_strdup(value); + } else if (g_str_equal(key, "WiFi.NetAccessKey")) { + g_free(network->wifi.net_access_key); + network->wifi.net_access_key = g_strdup(value); + } else if (g_str_equal(key, "WiFi.RoamingCurBSSID")) { + g_free(network->wifi.roaming_cur_bssid); + network->wifi.roaming_cur_bssid = g_strdup(value); + } else if (g_str_equal(key, "WiFi.RoamingDstBSSID")) { + g_free(network->wifi.roaming_dst_bssid); + network->wifi.roaming_dst_bssid = g_strdup(value); +#endif } else { return -EINVAL; } @@ -2287,10 +2970,6 @@ int connman_network_set_string(struct connman_network *network, const char *connman_network_get_string(struct connman_network *network, const char *key) { -#if !defined TIZEN_EXT - DBG("network %p key %s", network, key); -#endif - if (g_str_equal(key, "Path")) return network->path; else if (g_str_equal(key, "Name")) @@ -2300,25 +2979,27 @@ const char *connman_network_get_string(struct connman_network *network, else if (g_str_equal(key, "WiFi.Mode")) return network->wifi.mode; else if (g_str_equal(key, "WiFi.Security")) -#if defined TIZEN_EXT - if (network->wifi.rsn_mode != true || - g_str_equal(network->wifi.security, "ieee8021x")) - return network->wifi.security; - else - return "rsn"; -#else return network->wifi.security; -#endif else if (g_str_equal(key, "WiFi.Passphrase")) return network->wifi.passphrase; else if (g_str_equal(key, "WiFi.EAP")) return network->wifi.eap; else if (g_str_equal(key, "WiFi.Identity")) return network->wifi.identity; + else if (g_str_equal(key, "WiFi.AnonymousIdentity")) + return network->wifi.anonymous_identity; else if (g_str_equal(key, "WiFi.AgentIdentity")) return network->wifi.agent_identity; else if (g_str_equal(key, "WiFi.CACertFile")) return network->wifi.ca_cert_path; + else if (g_str_equal(key, "WiFi.SubjectMatch")) + return network->wifi.subject_match; + else if (g_str_equal(key, "WiFi.AltSubjectMatch")) + return network->wifi.altsubject_match; + else if (g_str_equal(key, "WiFi.DomainSuffixMatch")) + return network->wifi.domain_suffix_match; + else if (g_str_equal(key, "WiFi.DomainMatch")) + return network->wifi.domain_match; else if (g_str_equal(key, "WiFi.ClientCertFile")) return network->wifi.client_cert_path; else if (g_str_equal(key, "WiFi.PrivateKeyFile")) @@ -2329,6 +3010,18 @@ const char *connman_network_get_string(struct connman_network *network, return network->wifi.phase2_auth; else if (g_str_equal(key, "WiFi.PinWPS")) return network->wifi.pin_wps; +#if defined TIZEN_EXT + else if (g_str_equal(key, "WiFi.Connector")) + return network->wifi.connector; + else if (g_str_equal(key, "WiFi.CSignKey")) + return network->wifi.c_sign_key; + else if (g_str_equal(key, "WiFi.NetAccessKey")) + return network->wifi.net_access_key; + else if (g_str_equal(key, "WiFi.RoamingCurBSSID")) + return network->wifi.roaming_cur_bssid; + else if (g_str_equal(key, "WiFi.RoamingDstBSSID")) + return network->wifi.roaming_dst_bssid; +#endif return NULL; } @@ -2344,14 +3037,12 @@ const char *connman_network_get_string(struct connman_network *network, int connman_network_set_bool(struct connman_network *network, const char *key, bool value) { -#if !defined TIZEN_EXT - DBG("network %p key %s value %d", network, key, value); -#endif - if (g_strcmp0(key, "Roaming") == 0) network->roaming = value; else if (g_strcmp0(key, "WiFi.WPS") == 0) network->wifi.wps = value; + else if (g_strcmp0(key, "WiFi.WPSAdvertising") == 0) + network->wifi.wps_advertizing = value; else if (g_strcmp0(key, "WiFi.UseWPS") == 0) network->wifi.use_wps = value; #if defined TIZEN_EXT @@ -2359,6 +3050,14 @@ int connman_network_set_bool(struct connman_network *network, network->default_internet = value; else if (g_strcmp0(key, "WiFi.HS20AP") == 0) network->wifi.isHS20AP = value; + else if (g_strcmp0(key, "WiFi.TRANSITION_MODE") == 0) + network->wifi.owe_transition_mode = value; + else if (g_strcmp0(key, "WiFi.Roaming") == 0) + network->wifi.roaming_progress = value; + else if (g_strcmp0(key, "WiFi.RoamingDHCP") == 0) + network->wifi.roaming_dhcp = value; + else if (g_strcmp0(key, "WiFi.PMFRequired") == 0) + network->wifi.pmf_required = value; #endif return -EINVAL; @@ -2374,14 +3073,12 @@ int connman_network_set_bool(struct connman_network *network, bool connman_network_get_bool(struct connman_network *network, const char *key) { -#if !defined TIZEN_EXT - DBG("network %p key %s", network, key); -#endif - if (g_str_equal(key, "Roaming")) return network->roaming; else if (g_str_equal(key, "WiFi.WPS")) return network->wifi.wps; + else if (g_str_equal(key, "WiFi.WPSAdvertising")) + return network->wifi.wps_advertizing; else if (g_str_equal(key, "WiFi.UseWPS")) return network->wifi.use_wps; #if defined TIZEN_EXT @@ -2389,6 +3086,14 @@ bool connman_network_get_bool(struct connman_network *network, return network->default_internet; else if (g_str_equal(key, "WiFi.HS20AP")) return network->wifi.isHS20AP; + else if (g_str_equal(key, "WiFi.TRANSITION_MODE")) + return network->wifi.owe_transition_mode; + else if (g_str_equal(key, "WiFi.Roaming")) + return network->wifi.roaming_progress; + else if (g_str_equal(key, "WiFi.RoamingDHCP")) + return network->wifi.roaming_dhcp; + else if (g_str_equal(key, "WiFi.PMFRequired")) + return network->wifi.pmf_required; #endif return false; @@ -2404,6 +3109,7 @@ bool connman_network_get_bool(struct connman_network *network, */ void connman_network_set_vsie_list(struct connman_network *network, GSList *vsie_list) { + g_slist_free_full(network->wifi.vsie_list, g_free); network->wifi.vsie_list = vsie_list; } @@ -2431,10 +3137,6 @@ void *connman_network_get_vsie_list(struct connman_network *network) int connman_network_set_blob(struct connman_network *network, const char *key, const void *data, unsigned int size) { -#if !defined TIZEN_EXT - DBG("network %p key %s size %d", network, key, size); -#endif - if (g_str_equal(key, "WiFi.SSID")) { g_free(network->wifi.ssid); network->wifi.ssid = g_try_malloc(size); @@ -2443,6 +3145,16 @@ int connman_network_set_blob(struct connman_network *network, network->wifi.ssid_len = size; } else network->wifi.ssid_len = 0; +#ifdef TIZEN_EXT + } else if (g_str_equal(key, "WiFi.TRANSITION_MODE_SSID")) { + g_free(network->wifi.transition_mode_ssid); + network->wifi.transition_mode_ssid = g_try_malloc(size); + if (network->wifi.transition_mode_ssid) { + memcpy(network->wifi.transition_mode_ssid, data, size); + network->wifi.transition_mode_ssid_len = size; + } else + network->wifi.transition_mode_ssid_len = 0; +#endif } else { return -EINVAL; } @@ -2461,14 +3173,16 @@ int connman_network_set_blob(struct connman_network *network, const void *connman_network_get_blob(struct connman_network *network, const char *key, unsigned int *size) { -#if !defined TIZEN_EXT - DBG("network %p key %s", network, key); -#endif - if (g_str_equal(key, "WiFi.SSID")) { if (size) *size = network->wifi.ssid_len; return network->wifi.ssid; +#ifdef TIZEN_EXT + } else if (g_str_equal(key, "WiFi.TRANSITION_MODE_SSID")) { + if (size) + *size = network->wifi.transition_mode_ssid_len; + return network->wifi.transition_mode_ssid; +#endif } return NULL;