diff options
Diffstat (limited to 'src/network.c')
-rwxr-xr-x[-rw-r--r--] | src/network.c | 478 |
1 files changed, 470 insertions, 8 deletions
diff --git a/src/network.c b/src/network.c index ed56210f..d38fc0af 100644..100755 --- a/src/network.c +++ b/src/network.c @@ -41,6 +41,18 @@ */ #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 + * RTR_SOLICITATION_INTERVAL(4) seconds to obtain RA for IPv6 auto-configuration. + */ +#define RTR_SOLICITATION_INTERVAL 4 + static GSList *network_list = NULL; static GSList *driver_list = NULL; @@ -92,8 +104,26 @@ struct connman_network { bool wps; 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; + bool isHS20AP; + unsigned int keymgmt; + char *keymgmt_type; + bool rsn_mode; + int disconnect_reason; + int assoc_status_code; + void *wifi_vsie; + unsigned int wifi_vsie_len; +#endif } wifi; +#if defined TIZEN_EXT + /* Multiple APN services and a default APN which a user selected */ + bool default_internet; +#endif + }; static const char *type2string(enum connman_network_type type) @@ -167,7 +197,11 @@ static void dhcp_success(struct connman_network *network) 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; @@ -233,7 +267,11 @@ static int set_connected_manual(struct connman_network *network) if (err < 0) goto err; +#if defined TIZEN_EXT + err = __connman_ipconfig_gateway_add(ipconfig, service); +#else err = __connman_ipconfig_gateway_add(ipconfig); +#endif if (err < 0) goto err; @@ -287,7 +325,11 @@ static int manual_ipv6_set(struct connman_network *network, return err; } +#if defined TIZEN_EXT + err = __connman_ipconfig_gateway_add(ipconfig_ipv6, service); +#else err = __connman_ipconfig_gateway_add(ipconfig_ipv6); +#endif if (err < 0) return err; @@ -427,10 +469,13 @@ static void check_dhcpv6(struct nd_router_advert *reply, DBG("re-send router solicitation %d", network->router_solicit_count); network->router_solicit_count--; - __connman_inet_ipv6_send_rs(network->index, 1, + __connman_inet_ipv6_send_rs(network->index, RTR_SOLICITATION_INTERVAL, check_dhcpv6, network); return; } +#if defined TIZEN_EXT + DBG("RA message is not received from server in reply of RS."); +#endif connman_network_unref(network); return; } @@ -443,6 +488,9 @@ static void check_dhcpv6(struct nd_router_advert *reply, */ if (!network->connected) { connman_network_unref(network); +#if defined TIZEN_EXT + DBG("Network is not connected"); +#endif return; } @@ -471,11 +519,21 @@ static void check_dhcpv6(struct nd_router_advert *reply, * We do stateful/stateless DHCPv6 if router advertisement says so. */ if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) { +#if defined TIZEN_EXT + DBG("IPv6 ND_RA_FLAG_MANAGED"); +#endif __connman_dhcpv6_start(network, prefixes, dhcpv6_callback); } else { if (reply->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) +#if defined TIZEN_EXT + { + DBG("IPv6 ND_RA_FLAG_OTHER"); +#endif __connman_dhcpv6_start_info(network, dhcpv6_info_callback); +#if defined TIZEN_EXT + } +#endif g_slist_free_full(prefixes, g_free); network->connecting = false; @@ -557,6 +615,11 @@ static void autoconf_ipv6_set(struct connman_network *network) __connman_device_set_network(network->device, network); +#if defined TIZEN_EXT + if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR) + return; +#endif + service = connman_service_lookup_from_network(network); if (!service) return; @@ -577,7 +640,8 @@ static void autoconf_ipv6_set(struct connman_network *network) /* Try to get stateless DHCPv6 information, RFC 3736 */ network->router_solicit_count = 3; - __connman_inet_ipv6_send_rs(index, 1, check_dhcpv6, network); + __connman_inet_ipv6_send_rs(index, RTR_SOLICITATION_INTERVAL, + check_dhcpv6, network); } static void set_connected(struct connman_network *network) @@ -690,12 +754,22 @@ static void set_disconnected(struct connman_network *network) CONNMAN_IPCONFIG_TYPE_IPV6); if (network->connected) { +#if defined TIZEN_EXT + /** + * Do not remove gateway and its address, + * if there are connected profiles that use same interface (multiple PDN) + */ + if (connman_service_get_type(service) != CONNMAN_SERVICE_TYPE_CELLULAR || + __connman_service_get_connected_count_of_iface(service) <= 0) { +#endif __connman_connection_gateway_remove(service, CONNMAN_IPCONFIG_TYPE_ALL); __connman_ipconfig_address_unset(ipconfig_ipv4); __connman_ipconfig_address_unset(ipconfig_ipv6); - +#if defined TIZEN_EXT + } +#endif /* * Special handling for IPv6 autoconfigured address. * The simplest way to remove autoconfigured routes is to @@ -905,7 +979,9 @@ static void network_destruct(struct connman_network *network) g_free(network->wifi.private_key_passphrase); g_free(network->wifi.phase2_auth); g_free(network->wifi.pin_wps); - +#if defined TIZEN_EXT + g_free(network->wifi.wifi_vsie); +#endif g_free(network->path); g_free(network->group); g_free(network->node); @@ -1147,6 +1223,15 @@ bool __connman_network_get_weakness(struct connman_network *network) return false; } +#if defined TIZEN_EXT +void connman_network_set_connecting(struct connman_network *network) +{ + DBG("set network connecting true"); + network->connecting = TRUE; + return; +} +#endif + bool connman_network_get_connecting(struct connman_network *network) { return network->connecting; @@ -1162,7 +1247,9 @@ bool connman_network_get_connecting(struct connman_network *network) int connman_network_set_available(struct connman_network *network, bool available) { +#if !defined TIZEN_EXT DBG("network %p available %d", network, available); +#endif if (network->available == available) return -EALREADY; @@ -1183,6 +1270,113 @@ bool connman_network_get_available(struct connman_network *network) return network->available; } +#if defined TIZEN_EXT +void connman_network_clear_associating(struct connman_network *network) +{ + struct connman_service *service; + enum connman_service_state state; + + DBG("network %p", network); + + network->connecting = FALSE; + network->associating = FALSE; + + service = connman_service_lookup_from_network(network); + if (!service) + return; + + state = __connman_service_ipconfig_get_state(service, + CONNMAN_IPCONFIG_TYPE_IPV4); + if (state != CONNMAN_SERVICE_STATE_IDLE && + state != CONNMAN_SERVICE_STATE_FAILURE) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_DISCONNECT, + CONNMAN_IPCONFIG_TYPE_IPV4); + + state = __connman_service_ipconfig_get_state(service, + CONNMAN_IPCONFIG_TYPE_IPV6); + if (state != CONNMAN_SERVICE_STATE_IDLE && + state != CONNMAN_SERVICE_STATE_FAILURE) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_DISCONNECT, + CONNMAN_IPCONFIG_TYPE_IPV6); + + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV4); + + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV6); +} + +static gboolean __connman_network_clear_associating_delayed(gpointer user_data) +{ + GSList *list; + gboolean found = FALSE; + enum connman_service_state state_ipv4; + enum connman_service_state state_ipv6; + struct connman_service *service; + struct connman_network *network = (struct connman_network *)user_data; + + for (list = network_list; list != NULL; list = list->next) { + struct connman_network *item = list->data; + + if (item == network) { + found = TRUE; + break; + } + } + + if (found != TRUE) + return FALSE; + + DBG("network %p name %s", network, network->name); + service = connman_service_lookup_from_network(network); + + state_ipv4 = __connman_service_ipconfig_get_state(service, + CONNMAN_IPCONFIG_TYPE_IPV4); + state_ipv6 = __connman_service_ipconfig_get_state(service, + CONNMAN_IPCONFIG_TYPE_IPV6); + + DBG("service %p state %d/%d", service, state_ipv4, state_ipv6); + + if (network->associating == FALSE && + state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION && + state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION) { + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV4); + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV6); + } else { + if (network->associating == FALSE) { + struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6; + enum connman_ipconfig_method ipv4_method, ipv6_method; + + ipconfig_ipv4 = __connman_service_get_ip4config(service); + ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4); + ipconfig_ipv6 = __connman_service_get_ip4config(service); + ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6); + + if((ipv4_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv4_method == CONNMAN_IPCONFIG_METHOD_OFF) && + (state_ipv6 == CONNMAN_SERVICE_STATE_ASSOCIATION)) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV6); + if((ipv6_method == CONNMAN_IPCONFIG_METHOD_UNKNOWN || ipv6_method == CONNMAN_IPCONFIG_METHOD_OFF) && + (state_ipv4 == CONNMAN_SERVICE_STATE_ASSOCIATION)) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV4); + } + } + + return FALSE; +} +#endif + /** * connman_network_set_associating: * @network: network structure @@ -1212,6 +1406,14 @@ int connman_network_set_associating(struct connman_network *network, CONNMAN_IPCONFIG_TYPE_IPV6); } +#if defined TIZEN_EXT + if (associating == FALSE && + connman_network_get_bool(network, "WiFi.UseWPS") == FALSE) + g_timeout_add_seconds(1, + __connman_network_clear_associating_delayed, + network); +#endif + return 0; } @@ -1221,8 +1423,13 @@ static void set_associate_error(struct connman_network *network) service = connman_service_lookup_from_network(network); +#if defined TIZEN_EXT + __connman_service_indicate_error(service, + CONNMAN_SERVICE_ERROR_AUTH_FAILED); +#else __connman_service_indicate_error(service, CONNMAN_SERVICE_ERROR_CONNECT_FAILED); +#endif } static void set_configure_error(struct connman_network *network) @@ -1241,6 +1448,10 @@ static void set_invalid_key_error(struct connman_network *network) service = connman_service_lookup_from_network(network); +#if defined TIZEN_EXT + if (service) + __connman_service_set_favorite(service, false); +#endif __connman_service_indicate_error(service, CONNMAN_SERVICE_ERROR_INVALID_KEY); } @@ -1265,6 +1476,22 @@ static void set_blocked_error(struct connman_network *network) CONNMAN_SERVICE_ERROR_BLOCKED); } + +#if defined TIZEN_EXT +static void set_dhcp_error(struct connman_network *network) +{ + struct connman_service *service; + + if (network->associating != FALSE) + network->associating = FALSE; + + service = connman_service_lookup_from_network(network); + + __connman_service_indicate_error(service, + CONNMAN_SERVICE_ERROR_DHCP_FAILED); +} +#endif + void connman_network_set_ipv4_method(struct connman_network *network, enum connman_ipconfig_method method) { @@ -1319,9 +1546,16 @@ void connman_network_set_error(struct connman_network *network, case CONNMAN_NETWORK_ERROR_CONNECT_FAIL: set_connect_error(network); break; +#if defined TIZEN_EXT + case CONNMAN_NETWORK_ERROR_DHCP_FAIL: + set_dhcp_error(network); + break; +#endif + case CONNMAN_NETWORK_ERROR_BLOCKED: set_blocked_error(network); break; + } __connman_network_disconnect(network); @@ -1461,13 +1695,21 @@ int __connman_network_connect(struct connman_network *network) network->connecting = true; +#if defined TIZEN_EXT + if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR) +#endif __connman_device_disconnect(network->device); - +#if defined TIZEN_EXT + DBG("ConnMan, Connect Request [%s]", network->name); +#endif err = network->driver->connect(network); if (err < 0) { - if (err == -EINPROGRESS) + if (err == -EINPROGRESS) { +#if defined TIZEN_EXT + if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR) +#endif connman_network_set_associating(network, true); - else + } else network->connecting = false; return err; @@ -1498,7 +1740,9 @@ int __connman_network_disconnect(struct connman_network *network) return -EUNATCH; network->connecting = false; - +#if defined TIZEN_EXT + DBG("ConnMan, Disconnect request"); +#endif if (network->driver->disconnect) err = network->driver->disconnect(network); @@ -1552,12 +1796,38 @@ int __connman_network_clear_ipconfig(struct connman_network *network, return 0; } +#if defined TIZEN_EXT +void __connman_network_set_auto_ipv6_gateway(char *gateway, void *user_data) +{ + DBG(""); + + struct connman_network *network = user_data; + struct connman_service *service; + struct connman_ipconfig *ipconfig = NULL; + + service = connman_service_lookup_from_network(network); + if (service == NULL) + return; + + ipconfig = __connman_service_get_ipconfig(service, AF_INET6); + if (ipconfig == NULL) + return; + + __connman_ipconfig_set_gateway(ipconfig, gateway); + + return; +} +#endif + int __connman_network_enable_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig) { int r = 0; enum connman_ipconfig_type type; enum connman_ipconfig_method method; +#if defined TIZEN_EXT + struct connman_service *service; +#endif if (!network || !ipconfig) return -EINVAL; @@ -1585,6 +1855,14 @@ int __connman_network_enable_ipconfig(struct connman_network *network, break; case CONNMAN_IPCONFIG_METHOD_AUTO: +#if defined TIZEN_EXT + service = connman_service_lookup_from_network(network); + + if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR) + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_CONFIGURATION, + CONNMAN_IPCONFIG_TYPE_IPV6); +#endif autoconf_ipv6_set(network); break; @@ -1661,6 +1939,142 @@ int connman_network_set_ipaddress(struct connman_network *network, return 0; } +#if defined TIZEN_EXT +/* + * Description: Network client requires additional wifi specific info + */ +int connman_network_set_bssid(struct connman_network *network, + const unsigned char *bssid) +{ + int i = 0; + + 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]); + + for (;i < WIFI_BSSID_LEN_MAX;i++) + network->wifi.bssid[i] = bssid[i]; + + return 0; +} + +unsigned char *connman_network_get_bssid(struct connman_network *network) +{ + return (unsigned char *)network->wifi.bssid; +} + +int connman_network_set_maxrate(struct connman_network *network, + unsigned int maxrate) +{ +#if !defined TIZEN_EXT + DBG("network %p maxrate %d", network, maxrate); +#endif + + network->wifi.maxrate = maxrate; + + return 0; +} + +unsigned int connman_network_get_maxrate(struct connman_network *network) +{ + return network->wifi.maxrate; +} + +int connman_network_set_enc_mode(struct connman_network *network, + const char *encryption_mode) +{ + if (encryption_mode == NULL) + return -EINVAL; + + DBG("network %p encryption mode %s", network, encryption_mode); + + g_strlcpy(network->wifi.encryption_mode, encryption_mode, + WIFI_ENCYPTION_MODE_LEN_MAX); + + return 0; +} + +const char *connman_network_get_enc_mode(struct connman_network *network) +{ + return (const char *)network->wifi.encryption_mode; +} + +int connman_network_set_rsn_mode(struct connman_network *network, + bool rsn_mode) +{ + network->wifi.rsn_mode = rsn_mode; + + return 0; +} + +int connman_network_set_proxy(struct connman_network *network, + const char *proxies) +{ + struct connman_service *service; + + DBG("network %p proxies %s", network, proxies); + + service = connman_service_lookup_from_network(network); + if (service == NULL) + return -EINVAL; + + __connman_service_set_proxy(service, proxies); + + connman_service_set_proxy_method(service, + CONNMAN_SERVICE_PROXY_METHOD_MANUAL); + + return 0; +} + +int connman_network_set_keymgmt(struct connman_network *network, + unsigned int keymgmt) +{ + if (network == NULL) + return 0; + + network->wifi.keymgmt = keymgmt; + + return 0; +} + +unsigned int connman_network_get_keymgmt(struct connman_network *network) +{ + if (network == NULL) + return 0; + + return network->wifi.keymgmt; +} + +int connman_network_set_disconnect_reason(struct connman_network *network, + int reason_code) +{ + if (network == NULL) + return 0; + + network->wifi.disconnect_reason = reason_code; + + return 0; +} + +int connman_network_get_disconnect_reason(struct connman_network *network) +{ + if (network == NULL) + return 0; + + return network->wifi.disconnect_reason; +} +int connman_network_get_assoc_status_code(struct connman_network *network) +{ + if (network == NULL) + return 0; + + return network->wifi.assoc_status_code; +} +#endif + int connman_network_set_nameservers(struct connman_network *network, const char *nameservers) { @@ -1682,8 +2096,14 @@ int connman_network_set_nameservers(struct connman_network *network, nameservers_array = g_strsplit(nameservers, " ", 0); for (i = 0; nameservers_array[i]; i++) { +#if defined TIZEN_EXT + __connman_service_nameserver_append(service, + nameservers_array[i], false, + CONNMAN_IPCONFIG_TYPE_ALL); +#else __connman_service_nameserver_append(service, nameservers_array[i], false); +#endif } g_strfreev(nameservers_array); @@ -1799,6 +2219,9 @@ int connman_network_set_string(struct connman_network *network, g_free(network->wifi.security); network->wifi.security = g_strdup(value); } else if (g_str_equal(key, "WiFi.Passphrase")) { +#if defined TIZEN_EXT + DBG("ConnMan, %p key %s", network, key); +#endif g_free(network->wifi.passphrase); network->wifi.passphrase = g_strdup(value); } else if (g_str_equal(key, "WiFi.EAP")) { @@ -1869,7 +2292,15 @@ 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")) @@ -1921,6 +2352,12 @@ int connman_network_set_bool(struct connman_network *network, network->wifi.wps = value; else if (g_strcmp0(key, "WiFi.UseWPS") == 0) network->wifi.use_wps = value; +#if defined TIZEN_EXT + else if (g_strcmp0(key, "DefaultInternet") == 0) + network->default_internet = value; + else if (g_strcmp0(key, "WiFi.HS20AP") == 0) + network->wifi.isHS20AP = value; +#endif return -EINVAL; } @@ -1941,6 +2378,12 @@ bool connman_network_get_bool(struct connman_network *network, return network->wifi.wps; else if (g_str_equal(key, "WiFi.UseWPS")) return network->wifi.use_wps; +#if defined TIZEN_EXT + else if (g_str_equal(key, "DefaultInternet")) + return network->default_internet; + else if (g_str_equal(key, "WiFi.HS20AP")) + return network->wifi.isHS20AP; +#endif return false; } @@ -1965,6 +2408,16 @@ int connman_network_set_blob(struct connman_network *network, network->wifi.ssid_len = size; } else network->wifi.ssid_len = 0; +#if defined TIZEN_EXT + } else if (g_str_equal(key, "WiFi.Vsie")){ + g_free(network->wifi.wifi_vsie); + network->wifi.wifi_vsie = g_try_malloc(size); + if (network->wifi.wifi_vsie) { + memcpy(network->wifi.wifi_vsie, data, size); + network->wifi.wifi_vsie_len = size; + } else + network->wifi.wifi_vsie_len = 0; +#endif } else { return -EINVAL; } @@ -1989,6 +2442,15 @@ const void *connman_network_get_blob(struct connman_network *network, return network->wifi.ssid; } +#if defined TIZEN_EXT + if (g_str_equal(key, "WiFi.Vsie")) { + if (size) + *size = network->wifi.wifi_vsie_len; + + return network->wifi.wifi_vsie; + } +#endif + return NULL; } |