X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fnetwork.c;h=e189955c2ad7931dc6ebbda1db7982e6c289237b;hb=d04bfa0350781ebfb8cbb2e64fabdfb2f36cd302;hp=42158337af6c72fe7daf5ca36aef587671f704a5;hpb=38d0ab199481b3d2fd699000016020af70ea54e8;p=platform%2Fupstream%2Fconnman.git diff --git a/src/network.c b/src/network.c old mode 100644 new mode 100755 index 4215833..e189955 --- a/src/network.c +++ b/src/network.c @@ -2,7 +2,7 @@ * * Connection Manager * - * Copyright (C) 2007-2012 Intel Corporation. All rights reserved. + * Copyright (C) 2007-2014 Intel Corporation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -41,17 +41,29 @@ */ #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; struct connman_network { int refcount; enum connman_network_type type; - connman_bool_t available; - connman_bool_t connected; - connman_bool_t roaming; - connman_uint8_t strength; - connman_uint16_t frequency; + bool available; + bool connected; + bool roaming; + uint8_t strength; + uint16_t frequency; char *identifier; char *name; char *node; @@ -64,8 +76,8 @@ struct connman_network { struct connman_network_driver *driver; void *driver_data; - connman_bool_t connecting; - connman_bool_t associating; + bool connecting; + bool associating; struct connman_device *device; @@ -76,20 +88,47 @@ struct connman_network { unsigned short channel; char *security; char *passphrase; - char *agent_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; - connman_bool_t wps; - connman_bool_t use_wps; + 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; + GSList *vsie_list; + /* + * Only for EAP-FAST + */ + char *phase1; + unsigned char country_code[WIFI_COUNTRY_CODE_LEN]; + GSList *bssid_list; +#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) @@ -100,6 +139,8 @@ static const char *type2string(enum connman_network_type type) break; case CONNMAN_NETWORK_TYPE_ETHERNET: return "ethernet"; + case CONNMAN_NETWORK_TYPE_GADGET: + return "gadget"; case CONNMAN_NETWORK_TYPE_WIFI: return "wifi"; case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN: @@ -112,14 +153,14 @@ static const char *type2string(enum connman_network_type type) return NULL; } -static gboolean match_driver(struct connman_network *network, +static bool match_driver(struct connman_network *network, struct connman_network_driver *driver) { if (network->type == driver->type || driver->type == CONNMAN_NETWORK_TYPE_UNKNOWN) - return TRUE; + return true; - return FALSE; + return false; } static void set_configuration(struct connman_network *network, @@ -129,13 +170,11 @@ static void set_configuration(struct connman_network *network, DBG("network %p", network); - if (network->device == NULL) + if (!network->device) return; __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, @@ -149,22 +188,30 @@ static void dhcp_success(struct connman_network *network) int err; service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) goto err; - connman_network_set_associating(network, FALSE); + ipconfig_ipv4 = __connman_service_get_ip4config(service); - network->connecting = FALSE; + DBG("lease acquired for ipconfig %p", ipconfig_ipv4); + + if (!ipconfig_ipv4) + return; - ipconfig_ipv4 = __connman_service_get_ip4config(service); 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: @@ -175,108 +222,82 @@ err: static void dhcp_failure(struct connman_network *network) { struct connman_service *service; + struct connman_ipconfig *ipconfig_ipv4; service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) return; - __connman_service_ipconfig_indicate_state(service, - CONNMAN_SERVICE_STATE_IDLE, - CONNMAN_IPCONFIG_TYPE_IPV4); + ipconfig_ipv4 = __connman_service_get_ip4config(service); + + DBG("lease lost for ipconfig %p", ipconfig_ipv4); + + if (!ipconfig_ipv4) + return; + + __connman_ipconfig_address_remove(ipconfig_ipv4); + __connman_ipconfig_gateway_remove(ipconfig_ipv4); } -static void dhcp_callback(struct connman_network *network, - connman_bool_t success) +static void dhcp_callback(struct connman_ipconfig *ipconfig, + struct connman_network *network, + bool success, gpointer data) { - DBG("success %d", success); + network->connecting = false; - if (success == TRUE) + if (success) dhcp_success(network); else dhcp_failure(network); } -static int set_connected_fixed(struct connman_network *network) -{ - struct connman_service *service; - struct connman_ipconfig *ipconfig_ipv4; - int err; - - DBG(""); - - service = connman_service_lookup_from_network(network); - - ipconfig_ipv4 = __connman_service_get_ip4config(service); - - set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4); - - network->connecting = FALSE; - - connman_network_set_associating(network, FALSE); - - err = __connman_ipconfig_address_add(ipconfig_ipv4); - if (err < 0) - goto err; - - err = __connman_ipconfig_gateway_add(ipconfig_ipv4); - if (err < 0) - goto err; - - return 0; - -err: - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); - - return err; -} - -static void set_connected_manual(struct connman_network *network) +static int set_connected_manual(struct connman_network *network) { + int err = 0; struct connman_service *service; struct connman_ipconfig *ipconfig; - int err; DBG("network %p", network); - service = connman_service_lookup_from_network(network); + network->connecting = false; + service = connman_service_lookup_from_network(network); ipconfig = __connman_service_get_ip4config(service); + __connman_ipconfig_enable(ipconfig); - if (__connman_ipconfig_get_local(ipconfig) == NULL) + if (!__connman_ipconfig_get_local(ipconfig)) __connman_service_read_ip4config(service); - set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4); - err = __connman_ipconfig_address_add(ipconfig); 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; - network->connecting = FALSE; - - connman_network_set_associating(network, FALSE); - - return; - err: - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); - return; + return err; } static int set_connected_dhcp(struct connman_network *network) { + struct connman_service *service; + struct connman_ipconfig *ipconfig_ipv4; int err; DBG("network %p", network); - set_configuration(network, CONNMAN_IPCONFIG_TYPE_IPV4); + service = connman_service_lookup_from_network(network); + ipconfig_ipv4 = __connman_service_get_ip4config(service); + __connman_ipconfig_enable(ipconfig_ipv4); - err = __connman_dhcp_start(network, dhcp_callback); + err = __connman_dhcp_start(ipconfig_ipv4, network, + dhcp_callback, NULL); if (err < 0) { connman_error("Can not request DHCP lease"); return err; @@ -294,10 +315,10 @@ static int manual_ipv6_set(struct connman_network *network, DBG("network %p ipv6 %p", network, ipconfig_ipv6); service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) return -EINVAL; - if (__connman_ipconfig_get_local(ipconfig_ipv6) == NULL) + if (!__connman_ipconfig_get_local(ipconfig_ipv6)) __connman_service_read_ip6config(service); __connman_ipconfig_enable_ipv6(ipconfig_ipv6); @@ -309,31 +330,35 @@ 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; - __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; + network->connecting = false; return 0; } static void stop_dhcpv6(struct connman_network *network) { + network->connecting = false; + __connman_dhcpv6_stop(network); } static void dhcpv6_release_callback(struct connman_network *network, - connman_bool_t success) + enum __connman_dhcpv6_status status, + gpointer data) { - DBG("success %d", success); + DBG("status %d", status); stop_dhcpv6(network); } @@ -345,36 +370,31 @@ static void release_dhcpv6(struct connman_network *network) } static void dhcpv6_info_callback(struct connman_network *network, - connman_bool_t success) + enum __connman_dhcpv6_status status, + gpointer data) { - DBG("success %d", success); + DBG("status %d", status); stop_dhcpv6(network); } -static gboolean dhcpv6_set_addresses(struct connman_network *network) +static int dhcpv6_set_addresses(struct connman_network *network) { struct connman_service *service; struct connman_ipconfig *ipconfig_ipv6; int err = -EINVAL; service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) goto err; - connman_network_set_associating(network, FALSE); - - network->connecting = FALSE; + network->connecting = false; ipconfig_ipv6 = __connman_service_get_ip6config(service); err = __connman_ipconfig_address_add(ipconfig_ipv6); if (err < 0) goto err; - err = __connman_ipconfig_gateway_add(ipconfig_ipv6); - if (err < 0) - goto err; - return 0; err: @@ -385,7 +405,7 @@ err: static void autoconf_ipv6_set(struct connman_network *network); static void dhcpv6_callback(struct connman_network *network, - connman_bool_t success); + enum __connman_dhcpv6_status status, gpointer data); /* * Have a separate callback for renew so that we do not do autoconf @@ -393,25 +413,30 @@ static void dhcpv6_callback(struct connman_network *network, * DHCPv6 solicitation. */ static void dhcpv6_renew_callback(struct connman_network *network, - connman_bool_t success) + enum __connman_dhcpv6_status status, + gpointer data) { - if (success == TRUE) - dhcpv6_callback(network, success); - else { + switch (status) { + case CONNMAN_DHCPV6_STATUS_SUCCEED: + dhcpv6_callback(network, status, data); + break; + case CONNMAN_DHCPV6_STATUS_FAIL: + case CONNMAN_DHCPV6_STATUS_RESTART: stop_dhcpv6(network); /* restart and do solicit again. */ autoconf_ipv6_set(network); + break; } } static void dhcpv6_callback(struct connman_network *network, - connman_bool_t success) + enum __connman_dhcpv6_status status, gpointer data) { - DBG("success %d", success); + DBG("status %d", status); /* Start the renew process if necessary */ - if (success == TRUE) { + if (status == CONNMAN_DHCPV6_STATUS_SUCCEED) { if (dhcpv6_set_addresses(network) < 0) { stop_dhcpv6(network); @@ -420,7 +445,13 @@ static void dhcpv6_callback(struct connman_network *network, if (__connman_dhcpv6_start_renew(network, dhcpv6_renew_callback) == -ETIMEDOUT) - dhcpv6_renew_callback(network, FALSE); + dhcpv6_renew_callback(network, + CONNMAN_DHCPV6_STATUS_FAIL, + data); + + } else if (status == CONNMAN_DHCPV6_STATUS_RESTART) { + stop_dhcpv6(network); + autoconf_ipv6_set(network); } else stop_dhcpv6(network); } @@ -429,11 +460,12 @@ static void check_dhcpv6(struct nd_router_advert *reply, unsigned int length, void *user_data) { struct connman_network *network = user_data; + struct connman_service *service; GSList *prefixes; DBG("reply %p", reply); - if (reply == NULL) { + if (!reply) { /* * Router solicitation message seem to get lost easily so * try to send it again. @@ -442,10 +474,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; } @@ -456,20 +491,58 @@ static void check_dhcpv6(struct nd_router_advert *reply, * If we were disconnected while waiting router advertisement, * we just quit and do not start DHCPv6 */ - if (network->connected == FALSE) { + if (!network->connected) { connman_network_unref(network); +#if defined TIZEN_EXT + DBG("Network is not connected"); +#endif return; } prefixes = __connman_inet_ipv6_get_prefixes(reply, length); /* + * If IPv6 config is missing from service, then create it. + * The ipconfig might be missing if we got a rtnl message + * that disabled IPv6 config and thus removed it. This + * can happen if we are switching from one service to + * another in the same interface. The only way to get IPv6 + * config back is to re-create it here. + */ + service = connman_service_lookup_from_network(network); + if (service) { + connman_service_create_ip6config(service, network->index); + + connman_network_set_associating(network, false); + + __connman_service_ipconfig_indicate_state(service, + CONNMAN_SERVICE_STATE_CONFIGURATION, + CONNMAN_IPCONFIG_TYPE_IPV6); + } + + /* * We do stateful/stateless DHCPv6 if router advertisement says so. */ - if (reply->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) + 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) - __connman_dhcpv6_start_info(network, dhcpv6_info_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; + } connman_network_unref(network); } @@ -481,7 +554,7 @@ static void receive_refresh_rs_reply(struct nd_router_advert *reply, DBG("reply %p", reply); - if (reply == NULL) { + if (!reply) { /* * Router solicitation message seem to get lost easily so * try to send it again. @@ -505,7 +578,8 @@ static void receive_refresh_rs_reply(struct nd_router_advert *reply, return; } -int __connman_refresh_rs_ipv6(struct connman_network *network, int index) +int __connman_network_refresh_rs_ipv6(struct connman_network *network, + int index) { int ret = 0; @@ -546,38 +620,46 @@ static void autoconf_ipv6_set(struct connman_network *network) __connman_device_set_network(network->device, network); - connman_device_set_disconnected(network->device, FALSE); - - network->connecting = FALSE; +#if defined TIZEN_EXT + if(network->type == CONNMAN_NETWORK_TYPE_CELLULAR) + return; +#endif service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) return; ipconfig = __connman_service_get_ip6config(service); - if (ipconfig == NULL) + if (!ipconfig) return; + __connman_ipconfig_enable(ipconfig); + + __connman_ipconfig_enable_ipv6(ipconfig); + + __connman_ipconfig_address_remove(ipconfig); + index = __connman_ipconfig_get_index(ipconfig); connman_network_ref(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) { struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6; - enum connman_ipconfig_method ipv4_method, ipv6_method; struct connman_service *service; - int ret; - if (network->connected == TRUE) + if (network->connected) return; - network->connected = TRUE; + connman_network_set_associating(network, false); + + network->connected = true; service = connman_service_lookup_from_network(network); @@ -587,56 +669,8 @@ static void set_connected(struct connman_network *network) DBG("service %p ipv4 %p ipv6 %p", service, ipconfig_ipv4, ipconfig_ipv6); - ipv4_method = __connman_ipconfig_get_method(ipconfig_ipv4); - ipv6_method = __connman_ipconfig_get_method(ipconfig_ipv6); - - DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method); - - switch (ipv6_method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - break; - case CONNMAN_IPCONFIG_METHOD_DHCP: - case CONNMAN_IPCONFIG_METHOD_AUTO: - autoconf_ipv6_set(network); - break; - case CONNMAN_IPCONFIG_METHOD_FIXED: - case CONNMAN_IPCONFIG_METHOD_MANUAL: - ret = manual_ipv6_set(network, ipconfig_ipv6); - if (ret != 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return; - } - break; - } - - switch (ipv4_method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_AUTO: - return; - case CONNMAN_IPCONFIG_METHOD_FIXED: - if (set_connected_fixed(network) < 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return; - } - return; - case CONNMAN_IPCONFIG_METHOD_MANUAL: - set_connected_manual(network); - return; - case CONNMAN_IPCONFIG_METHOD_DHCP: - if (set_connected_dhcp(network) < 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return; - } - } - - network->connecting = FALSE; - - connman_network_set_associating(network, FALSE); + __connman_network_enable_ipconfig(network, ipconfig_ipv4); + __connman_network_enable_ipconfig(network, ipconfig_ipv6); } static void set_disconnected(struct connman_network *network) @@ -646,11 +680,6 @@ static void set_disconnected(struct connman_network *network) enum connman_service_state state; struct connman_service *service; - if (network->connected == FALSE) - return; - - network->connected = FALSE; - service = connman_service_lookup_from_network(network); ipconfig_ipv4 = __connman_service_get_ip4config(service); @@ -672,28 +701,40 @@ static void set_disconnected(struct connman_network *network) __connman_device_set_network(network->device, NULL); - switch (ipv6_method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_FIXED: - case CONNMAN_IPCONFIG_METHOD_MANUAL: - break; - case CONNMAN_IPCONFIG_METHOD_DHCP: - case CONNMAN_IPCONFIG_METHOD_AUTO: - release_dhcpv6(network); - break; - } + if (network->connected) { + switch (ipv6_method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + case CONNMAN_IPCONFIG_METHOD_FIXED: + case CONNMAN_IPCONFIG_METHOD_MANUAL: + break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + case CONNMAN_IPCONFIG_METHOD_AUTO: + release_dhcpv6(network); + break; + } - 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_DHCP: - __connman_dhcp_stop(network); - break; + switch (ipv4_method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + 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: + __connman_dhcp_stop(ipconfig_ipv4); + break; + } } /* @@ -717,21 +758,33 @@ static void set_disconnected(struct connman_network *network) CONNMAN_SERVICE_STATE_DISCONNECT, CONNMAN_IPCONFIG_TYPE_IPV6); - __connman_connection_gateway_remove(service, - CONNMAN_IPCONFIG_TYPE_ALL); - - __connman_ipconfig_address_unset(ipconfig_ipv4); - __connman_ipconfig_address_unset(ipconfig_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); - /* - * Special handling for IPv6 autoconfigured address. - * The simplest way to remove autoconfigured routes is to - * disable IPv6 temporarily so that kernel will do the cleanup - * automagically. - */ - if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) { - __connman_ipconfig_disable_ipv6(ipconfig_ipv6); - __connman_ipconfig_enable_ipv6(ipconfig_ipv6); + __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 + * disable IPv6 temporarily so that kernel will do the cleanup + * automagically. + */ + if (ipv6_method == CONNMAN_IPCONFIG_METHOD_AUTO) { + __connman_ipconfig_disable_ipv6(ipconfig_ipv6); + __connman_ipconfig_enable_ipv6(ipconfig_ipv6); + } } __connman_service_ipconfig_indicate_state(service, @@ -742,9 +795,10 @@ static void set_disconnected(struct connman_network *network) CONNMAN_SERVICE_STATE_IDLE, CONNMAN_IPCONFIG_TYPE_IPV6); - network->connecting = FALSE; + network->connecting = false; + network->connected = false; - connman_network_set_associating(network, FALSE); + connman_network_set_associating(network, false); } @@ -756,13 +810,13 @@ static int network_probe(struct connman_network *network) DBG("network %p name %s", network, network->name); - if (network->driver != NULL) + if (network->driver) return -EALREADY; for (list = driver_list; list; list = list->next) { driver = list->data; - if (match_driver(network, driver) == FALSE) { + if (!match_driver(network, driver)) { driver = NULL; continue; } @@ -775,10 +829,10 @@ static int network_probe(struct connman_network *network) driver = NULL; } - if (driver == NULL) + if (!driver) return -ENODEV; - if (network->group == NULL) + if (!network->group) return -EINVAL; switch (network->type) { @@ -786,12 +840,13 @@ static int network_probe(struct connman_network *network) case CONNMAN_NETWORK_TYPE_VENDOR: return 0; case CONNMAN_NETWORK_TYPE_ETHERNET: + case CONNMAN_NETWORK_TYPE_GADGET: case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN: case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN: case CONNMAN_NETWORK_TYPE_CELLULAR: case CONNMAN_NETWORK_TYPE_WIFI: network->driver = driver; - if (__connman_service_create_from_network(network) == NULL) { + if (!__connman_service_create_from_network(network)) { network->driver = NULL; return -EINVAL; } @@ -804,10 +859,10 @@ static void network_remove(struct connman_network *network) { DBG("network %p name %s", network, network->name); - if (network->driver == NULL) + if (!network->driver) return; - if (network->connected == TRUE) + if (network->connected) set_disconnected(network); switch (network->type) { @@ -815,11 +870,12 @@ static void network_remove(struct connman_network *network) case CONNMAN_NETWORK_TYPE_VENDOR: break; case CONNMAN_NETWORK_TYPE_ETHERNET: + case CONNMAN_NETWORK_TYPE_GADGET: case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN: case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN: case CONNMAN_NETWORK_TYPE_CELLULAR: case CONNMAN_NETWORK_TYPE_WIFI: - if (network->group != NULL) { + if (network->group) { __connman_service_remove_from_network(network); g_free(network->group); @@ -834,33 +890,16 @@ static void network_remove(struct connman_network *network) network->driver = NULL; } -static void network_change(struct connman_network *network) -{ - DBG("network %p name %s", network, network->name); - - if (network->connected == FALSE) - return; - - connman_device_set_disconnected(network->device, TRUE); - - if (network->driver && network->driver->disconnect) { - network->driver->disconnect(network); - return; - } - - network->connected = FALSE; -} - static void probe_driver(struct connman_network_driver *driver) { GSList *list; DBG("driver %p name %s", driver, driver->name); - for (list = network_list; list != NULL; list = list->next) { + for (list = network_list; list; list = list->next) { struct connman_network *network = list->data; - if (network->driver != NULL) + if (network->driver) continue; if (driver->type != network->type) @@ -873,20 +912,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 != NULL; 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; @@ -923,11 +948,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) @@ -938,17 +970,24 @@ static void network_destruct(struct connman_network *network) g_free(network->wifi.mode); g_free(network->wifi.security); g_free(network->wifi.passphrase); - g_free(network->wifi.agent_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); +#endif g_free(network->path); g_free(network->group); g_free(network->node); @@ -974,19 +1013,15 @@ 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 == NULL) + if (!network) return NULL; - DBG("network %p", network); - network->refcount = 1; ident = g_strdup(identifier); - if (ident == NULL) { + if (!ident) { g_free(network); return NULL; } @@ -996,6 +1031,8 @@ struct connman_network *connman_network_create(const char *identifier, network_list = g_slist_prepend(network_list, network); + DBG("network %p identifier %s type %s", network, identifier, + type2string(type)); return network; } @@ -1048,7 +1085,8 @@ const char *__connman_network_get_type(struct connman_network *network) * * Get type of network */ -enum connman_network_type connman_network_get_type(struct connman_network *network) +enum connman_network_type connman_network_get_type( + struct connman_network *network) { return network->type; } @@ -1077,18 +1115,25 @@ void connman_network_set_index(struct connman_network *network, int index) struct connman_ipconfig *ipconfig; service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) goto done; ipconfig = __connman_service_get_ip4config(service); - if (ipconfig == NULL) - goto done; + if (ipconfig) { + __connman_ipconfig_set_index(ipconfig, index); - /* If index changed, the index of ipconfig must be reset. */ - __connman_ipconfig_set_index(ipconfig, index); + DBG("index %d service %p ip4config %p", network->index, + service, ipconfig); + } + + ipconfig = __connman_service_get_ip6config(service); + if (ipconfig) { + __connman_ipconfig_set_index(ipconfig, index); + + DBG("index %d service %p ip6config %p", network->index, + service, ipconfig); + } - DBG("index %d service %p ip4config %p", network->index, - service, ipconfig); done: network->index = index; } @@ -1119,6 +1164,7 @@ void connman_network_set_group(struct connman_network *network, case CONNMAN_NETWORK_TYPE_VENDOR: return; case CONNMAN_NETWORK_TYPE_ETHERNET: + case CONNMAN_NETWORK_TYPE_GADGET: case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN: case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN: case CONNMAN_NETWORK_TYPE_CELLULAR: @@ -1127,12 +1173,12 @@ void connman_network_set_group(struct connman_network *network, } if (g_strcmp0(network->group, group) == 0) { - if (group != NULL) + if (group) __connman_service_update_from_network(network); return; } - if (network->group != NULL) { + if (network->group) { __connman_service_remove_from_network(network); g_free(network->group); @@ -1140,7 +1186,7 @@ void connman_network_set_group(struct connman_network *network, network->group = g_strdup(group); - if (network->group != NULL) + if (network->group) network_probe(network); } @@ -1157,34 +1203,42 @@ const char *connman_network_get_group(struct connman_network *network) const char *__connman_network_get_ident(struct connman_network *network) { - if (network->device == NULL) + if (!network->device) return NULL; return connman_device_get_ident(network->device); } -connman_bool_t __connman_network_get_weakness(struct connman_network *network) +bool __connman_network_get_weakness(struct connman_network *network) { switch (network->type) { case CONNMAN_NETWORK_TYPE_UNKNOWN: case CONNMAN_NETWORK_TYPE_VENDOR: case CONNMAN_NETWORK_TYPE_ETHERNET: + case CONNMAN_NETWORK_TYPE_GADGET: case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN: case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN: case CONNMAN_NETWORK_TYPE_CELLULAR: break; case CONNMAN_NETWORK_TYPE_WIFI: - if (g_strcmp0(network->wifi.mode, "adhoc") == 0) - return TRUE; if (network->strength > 0 && network->strength < 20) - return TRUE; + return true; break; } - return FALSE; + 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 -connman_bool_t connman_network_get_connecting(struct connman_network *network) +bool connman_network_get_connecting(struct connman_network *network) { return network->connecting; } @@ -1197,9 +1251,11 @@ connman_bool_t connman_network_get_connecting(struct connman_network *network) * Change availability state of network (in range) */ int connman_network_set_available(struct connman_network *network, - connman_bool_t available) + bool available) { +#if !defined TIZEN_EXT DBG("network %p available %d", network, available); +#endif if (network->available == available) return -EALREADY; @@ -1215,11 +1271,118 @@ int connman_network_set_available(struct connman_network *network, * * Get network available setting */ -connman_bool_t connman_network_get_available(struct connman_network *network) +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 @@ -1228,7 +1391,7 @@ connman_bool_t connman_network_get_available(struct connman_network *network) * Change associating state of network */ int connman_network_set_associating(struct connman_network *network, - connman_bool_t associating) + bool associating) { DBG("network %p associating %d", network, associating); @@ -1237,7 +1400,7 @@ int connman_network_set_associating(struct connman_network *network, network->associating = associating; - if (associating == TRUE) { + if (associating) { struct connman_service *service; service = connman_service_lookup_from_network(network); @@ -1249,6 +1412,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; } @@ -1258,8 +1429,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) @@ -1278,6 +1454,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); } @@ -1292,6 +1472,32 @@ static void set_connect_error(struct connman_network *network) CONNMAN_SERVICE_ERROR_CONNECT_FAILED); } +static void set_blocked_error(struct connman_network *network) +{ + struct connman_service *service; + + service = connman_service_lookup_from_network(network); + + __connman_service_indicate_error(service, + 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) { @@ -1299,11 +1505,11 @@ void connman_network_set_ipv4_method(struct connman_network *network, struct connman_ipconfig *ipconfig; service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) return; ipconfig = __connman_service_get_ip4config(service); - if (ipconfig == NULL) + if (!ipconfig) return; __connman_ipconfig_set_method(ipconfig, method); @@ -1316,11 +1522,11 @@ void connman_network_set_ipv6_method(struct connman_network *network, struct connman_ipconfig *ipconfig; service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) return; ipconfig = __connman_service_get_ip6config(service); - if (ipconfig == NULL) + if (!ipconfig) return; __connman_ipconfig_set_method(ipconfig, method); @@ -1331,9 +1537,6 @@ void connman_network_set_error(struct connman_network *network, { DBG("network %p error %d", network, error); - network->connecting = FALSE; - network->associating = FALSE; - switch (error) { case CONNMAN_NETWORK_ERROR_UNKNOWN: return; @@ -1349,25 +1552,19 @@ void connman_network_set_error(struct connman_network *network, case CONNMAN_NETWORK_ERROR_CONNECT_FAIL: set_connect_error(network); break; - } - - network_change(network); -} - -void connman_network_clear_error(struct connman_network *network) -{ - struct connman_service *service; - - DBG("network %p", network); +#if defined TIZEN_EXT + case CONNMAN_NETWORK_ERROR_DHCP_FAIL: + set_dhcp_error(network); + break; +#endif - if (network == NULL) - return; + case CONNMAN_NETWORK_ERROR_BLOCKED: + set_blocked_error(network); + break; - if (network->connecting == TRUE || network->associating == TRUE) - return; + } - service = connman_service_lookup_from_network(network); - __connman_service_clear_error(service); + __connman_network_disconnect(network); } /** @@ -1378,24 +1575,23 @@ void connman_network_clear_error(struct connman_network *network) * Change connected state of network */ int connman_network_set_connected(struct connman_network *network, - connman_bool_t connected) + bool connected) { DBG("network %p connected %d/%d connecting %d associating %d", network, network->connected, connected, network->connecting, network->associating); - if ((network->connecting == TRUE || network->associating == TRUE) && - connected == FALSE) { + if ((network->connecting || network->associating) && + !connected) { connman_network_set_error(network, CONNMAN_NETWORK_ERROR_CONNECT_FAIL); - if (__connman_network_disconnect(network) == 0) - return 0; + return 0; } if (network->connected == connected) return -EALREADY; - if (connected == FALSE) + if (!connected) set_disconnected(network); else set_connected(network); @@ -1409,7 +1605,7 @@ int connman_network_set_connected(struct connman_network *network, * * Get network connection status */ -connman_bool_t connman_network_get_connected(struct connman_network *network) +bool connman_network_get_connected(struct connman_network *network) { return network->connected; } @@ -1420,14 +1616,14 @@ connman_bool_t connman_network_get_connected(struct connman_network *network) * * Get network associating status */ -connman_bool_t connman_network_get_associating(struct connman_network *network) +bool connman_network_get_associating(struct connman_network *network) { return network->associating; } void connman_network_clear_hidden(void *user_data) { - if (user_data == NULL) + if (!user_data) return; DBG("user_data %p", user_data); @@ -1438,11 +1634,11 @@ void connman_network_clear_hidden(void *user_data) * error to the caller telling that we could not find * any network that we could connect to. */ - __connman_service_reply_dbus_pending(user_data, EIO, NULL); + connman_dbus_reply_pending(user_data, EIO, NULL); } int connman_network_connect_hidden(struct connman_network *network, - char *identity, char* passphrase, void *user_data) + char *identity, char *passphrase, void *user_data) { int err = 0; struct connman_service *service; @@ -1451,16 +1647,14 @@ int connman_network_connect_hidden(struct connman_network *network, DBG("network %p service %p user_data %p", network, service, user_data); - if (service == NULL) { - err = -EINVAL; - goto out; - } + if (!service) + return -EINVAL; - if (identity != NULL) + if (identity) __connman_service_set_agent_identity(service, identity); - if (passphrase != NULL) - err = __connman_service_add_passphrase(service, passphrase); + if (passphrase) + err = __connman_service_set_passphrase(service, passphrase); if (err == -ENOKEY) { __connman_service_indicate_error(service, @@ -1468,9 +1662,9 @@ int connman_network_connect_hidden(struct connman_network *network, goto out; } else { __connman_service_set_hidden(service); - __connman_service_set_userconnect(service, TRUE); __connman_service_set_hidden_data(service, user_data); - return __connman_service_connect(service); + return __connman_service_connect(service, + CONNMAN_SERVICE_CONNECT_REASON_USER); } out: @@ -1490,32 +1684,39 @@ int __connman_network_connect(struct connman_network *network) DBG("network %p", network); - if (network->connected == TRUE) + if (network->connected) return -EISCONN; - if (network->connecting == TRUE || network->associating == TRUE) + if (network->connecting || network->associating) return -EALREADY; - if (network->driver == NULL) + if (!network->driver) return -EUNATCH; - if (network->driver->connect == NULL) + if (!network->driver->connect) return -ENOSYS; - if (network->device == NULL) + if (!network->device) return -ENODEV; - network->connecting = TRUE; + 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) - connman_network_set_associating(network, TRUE); - else { - network->connecting = FALSE; - } + if (err == -EINPROGRESS) { +#if defined TIZEN_EXT + if (network->type != CONNMAN_NETWORK_TYPE_CELLULAR) +#endif + connman_network_set_associating(network, true); + } else + network->connecting = false; return err; } @@ -1533,60 +1734,43 @@ int __connman_network_connect(struct connman_network *network) */ int __connman_network_disconnect(struct connman_network *network) { - int err; + int err = 0; DBG("network %p", network); - if (network->connected == FALSE && network->connecting == FALSE && - network->associating == FALSE) + if (!network->connected && !network->connecting && + !network->associating) return -ENOTCONN; - if (network->driver == NULL) + if (!network->driver) return -EUNATCH; - if (network->driver->disconnect == NULL) - return -ENOSYS; - - network->connecting = FALSE; + network->connecting = false; +#if defined TIZEN_EXT + DBG("ConnMan, Disconnect request"); +#endif + if (network->driver->disconnect) + err = network->driver->disconnect(network); - err = network->driver->disconnect(network); - if (err == 0) + if (err != -EINPROGRESS) set_disconnected(network); return err; } -static int manual_ipv4_set(struct connman_network *network, - struct connman_ipconfig *ipconfig) -{ - struct connman_service *service; - int err; - - service = connman_service_lookup_from_network(network); - if (service == NULL) - return -EINVAL; - - err = __connman_ipconfig_address_add(ipconfig); - if (err < 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); - return err; - } - - return __connman_ipconfig_gateway_add(ipconfig); -} - int __connman_network_clear_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig) { struct connman_service *service; + struct connman_ipconfig *ipconfig_ipv4; enum connman_ipconfig_method method; enum connman_ipconfig_type type; service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) return -EINVAL; + ipconfig_ipv4 = __connman_service_get_ip4config(service); method = __connman_ipconfig_get_method(ipconfig); type = __connman_ipconfig_get_config_type(ipconfig); @@ -1602,7 +1786,7 @@ int __connman_network_clear_ipconfig(struct connman_network *network, __connman_ipconfig_address_remove(ipconfig); break; case CONNMAN_IPCONFIG_METHOD_DHCP: - __connman_dhcp_stop(network); + __connman_dhcp_stop(ipconfig_ipv4); break; } @@ -1618,57 +1802,122 @@ int __connman_network_clear_ipconfig(struct connman_network *network, return 0; } -int __connman_network_set_ipconfig(struct connman_network *network, - struct connman_ipconfig *ipconfig_ipv4, - struct connman_ipconfig *ipconfig_ipv6) +#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; - int ret; +#if defined TIZEN_EXT + struct connman_service *service; +#endif - if (network == NULL) + if (!network || !ipconfig) return -EINVAL; - if (ipconfig_ipv6) { - method = __connman_ipconfig_get_method(ipconfig_ipv6); + type = __connman_ipconfig_get_config_type(ipconfig); + + switch (type) { + case CONNMAN_IPCONFIG_TYPE_UNKNOWN: + case CONNMAN_IPCONFIG_TYPE_ALL: + return -ENOSYS; + + case CONNMAN_IPCONFIG_TYPE_IPV6: + set_configuration(network, type); + + method = __connman_ipconfig_get_method(ipconfig); + + DBG("ipv6 ipconfig method %d", method); switch (method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + break; + case CONNMAN_IPCONFIG_METHOD_OFF: + __connman_ipconfig_disable_ipv6(ipconfig); 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; + case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: - ret = manual_ipv6_set(network, ipconfig_ipv6); - if (ret != 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); - return ret; - } + r = manual_ipv6_set(network, ipconfig); break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + r = -ENOSYS; break; } - } - if (ipconfig_ipv4) { - method = __connman_ipconfig_get_method(ipconfig_ipv4); + break; + + case CONNMAN_IPCONFIG_TYPE_IPV4: + set_configuration(network, type); + + method = __connman_ipconfig_get_method(ipconfig); + + DBG("ipv4 ipconfig method %d", method); switch (method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_FIXED: + break; + case CONNMAN_IPCONFIG_METHOD_AUTO: - return -EINVAL; + r = -ENOSYS; + break; + + case CONNMAN_IPCONFIG_METHOD_FIXED: case CONNMAN_IPCONFIG_METHOD_MANUAL: - return manual_ipv4_set(network, ipconfig_ipv4); + r = set_connected_manual(network); + break; + case CONNMAN_IPCONFIG_METHOD_DHCP: - return __connman_dhcp_start(network, dhcp_callback); + r = set_connected_dhcp(network); + break; } + + break; } - return 0; + if (r < 0) + connman_network_set_error(network, + CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); + + return r; } int connman_network_set_ipaddress(struct connman_network *network, @@ -1680,11 +1929,11 @@ int connman_network_set_ipaddress(struct connman_network *network, DBG("network %p", network); service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) return -EINVAL; ipconfig = __connman_service_get_ipconfig(service, ipaddress->family); - if (ipconfig == NULL) + if (!ipconfig) return -EINVAL; __connman_ipconfig_set_local(ipconfig, ipaddress->local); @@ -1696,6 +1945,178 @@ 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; +} + +int connman_network_set_countrycode(struct connman_network *network, + const unsigned char *country_code) +{ + int i = 0; + + if (country_code == NULL) + return -EINVAL; + + 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; +} + +unsigned char *connman_network_get_countrycode(struct connman_network *network) +{ + return (unsigned char *)network->wifi.country_code; +} + +int connman_network_set_bssid_list(struct connman_network *network, + GSList *bssids) +{ + g_slist_free_full(network->wifi.bssid_list, g_free); + network->wifi.bssid_list = bssids; + + return 0; +} + +void *connman_network_get_bssid_list(struct connman_network *network) +{ + return network->wifi.bssid_list; +} +#endif + int connman_network_set_nameservers(struct connman_network *network, const char *nameservers) { @@ -1706,19 +2127,25 @@ int connman_network_set_nameservers(struct connman_network *network, DBG("network %p nameservers %s", network, nameservers); service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) return -EINVAL; __connman_service_nameserver_clear(service); - if (nameservers == NULL) + if (!nameservers) return 0; nameservers_array = g_strsplit(nameservers, " ", 0); - for (i = 0; nameservers_array[i] != NULL; i++) { + 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); + nameservers_array[i], false); +#endif } g_strfreev(nameservers_array); @@ -1734,7 +2161,7 @@ int connman_network_set_domain(struct connman_network *network, DBG("network %p domain %s", network, domain); service = connman_service_lookup_from_network(network); - if (service == NULL) + if (!service) return -EINVAL; __connman_service_set_domainname(service, domain); @@ -1769,46 +2196,40 @@ int connman_network_set_name(struct connman_network *network, */ int connman_network_set_strength(struct connman_network *network, - connman_uint8_t strength) + uint8_t strength) { - DBG("network %p strengh %d", network, strength); - network->strength = strength; return 0; } -connman_uint8_t connman_network_get_strength(struct connman_network *network) +uint8_t connman_network_get_strength(struct connman_network *network) { return network->strength; } int connman_network_set_frequency(struct connman_network *network, - connman_uint16_t frequency) + uint16_t frequency) { - DBG("network %p frequency %d", network, frequency); - network->frequency = frequency; return 0; } -connman_uint16_t connman_network_get_frequency(struct connman_network *network) +uint16_t connman_network_get_frequency(struct connman_network *network) { return network->frequency; } int connman_network_set_wifi_channel(struct connman_network *network, - connman_uint16_t channel) + uint16_t channel) { - DBG("network %p wifi channel %d", network, channel); - network->wifi.channel = channel; return 0; } -connman_uint16_t connman_network_get_wifi_channel(struct connman_network *network) +uint16_t connman_network_get_wifi_channel(struct connman_network *network) { return network->wifi.channel; } @@ -1824,54 +2245,67 @@ connman_uint16_t connman_network_get_wifi_channel(struct connman_network *networ int connman_network_set_string(struct connman_network *network, const char *key, const char *value) { - DBG("network %p key %s value %s", network, key, value); - if (g_strcmp0(key, "Name") == 0) return connman_network_set_name(network, value); - if (g_str_equal(key, "Path") == TRUE) { + if (g_str_equal(key, "Path")) { g_free(network->path); network->path = g_strdup(value); - } else if (g_str_equal(key, "Node") == TRUE) { + } else if (g_str_equal(key, "Node")) { g_free(network->node); network->node = g_strdup(value); - } else if (g_str_equal(key, "WiFi.Mode") == TRUE) { + } else if (g_str_equal(key, "WiFi.Mode")) { g_free(network->wifi.mode); network->wifi.mode = g_strdup(value); - } else if (g_str_equal(key, "WiFi.Security") == TRUE) { + } else if (g_str_equal(key, "WiFi.Security")) { g_free(network->wifi.security); network->wifi.security = g_strdup(value); - } else if (g_str_equal(key, "WiFi.Passphrase") == TRUE) { + } 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.AgentPassphrase") == TRUE) { - g_free(network->wifi.agent_passphrase); - network->wifi.agent_passphrase = g_strdup(value); - } else if (g_str_equal(key, "WiFi.EAP") == TRUE) { + } else if (g_str_equal(key, "WiFi.EAP")) { g_free(network->wifi.eap); network->wifi.eap = g_strdup(value); - } else if (g_str_equal(key, "WiFi.Identity") == TRUE) { + } 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.AgentIdentity") == TRUE) { + } 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") == TRUE) { + } 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.ClientCertFile") == TRUE) { + } 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); - } else if (g_str_equal(key, "WiFi.PrivateKeyFile") == TRUE) { + } else if (g_str_equal(key, "WiFi.PrivateKeyFile")) { g_free(network->wifi.private_key_path); network->wifi.private_key_path = g_strdup(value); - } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase") == TRUE) { + } else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase")) { g_free(network->wifi.private_key_passphrase); network->wifi.private_key_passphrase = g_strdup(value); - } else if (g_str_equal(key, "WiFi.Phase2") == TRUE) { + } else if (g_str_equal(key, "WiFi.Phase2")) { g_free(network->wifi.phase2_auth); network->wifi.phase2_auth = g_strdup(value); - } else if (g_str_equal(key, "WiFi.PinWPS") == TRUE) { + } else if (g_str_equal(key, "WiFi.PinWPS")) { g_free(network->wifi.pin_wps); network->wifi.pin_wps = g_strdup(value); } else { @@ -1891,39 +2325,53 @@ int connman_network_set_string(struct connman_network *network, const char *connman_network_get_string(struct connman_network *network, const char *key) { - DBG("network %p key %s", network, key); - - if (g_str_equal(key, "Path") == TRUE) + if (g_str_equal(key, "Path")) return network->path; - else if (g_str_equal(key, "Name") == TRUE) + else if (g_str_equal(key, "Name")) return network->name; - else if (g_str_equal(key, "Node") == TRUE) + else if (g_str_equal(key, "Node")) return network->node; - else if (g_str_equal(key, "WiFi.Mode") == TRUE) + else if (g_str_equal(key, "WiFi.Mode")) return network->wifi.mode; - else if (g_str_equal(key, "WiFi.Security") == TRUE) + 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; - else if (g_str_equal(key, "WiFi.Passphrase") == TRUE) +#endif + else if (g_str_equal(key, "WiFi.Passphrase")) return network->wifi.passphrase; - else if (g_str_equal(key, "WiFi.AgentPassphrase") == TRUE) - return network->wifi.agent_passphrase; - else if (g_str_equal(key, "WiFi.EAP") == TRUE) + else if (g_str_equal(key, "WiFi.EAP")) return network->wifi.eap; - else if (g_str_equal(key, "WiFi.Identity") == TRUE) + else if (g_str_equal(key, "WiFi.Identity")) return network->wifi.identity; - else if (g_str_equal(key, "WiFi.AgentIdentity") == TRUE) + 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") == TRUE) + else if (g_str_equal(key, "WiFi.CACertFile")) return network->wifi.ca_cert_path; - else if (g_str_equal(key, "WiFi.ClientCertFile") == TRUE) + 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") == TRUE) + else if (g_str_equal(key, "WiFi.PrivateKeyFile")) return network->wifi.private_key_path; - else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase") == TRUE) + else if (g_str_equal(key, "WiFi.PrivateKeyPassphrase")) return network->wifi.private_key_passphrase; - else if (g_str_equal(key, "WiFi.Phase2") == TRUE) + else if (g_str_equal(key, "WiFi.Phase2")) return network->wifi.phase2_auth; - else if (g_str_equal(key, "WiFi.PinWPS") == TRUE) + else if (g_str_equal(key, "WiFi.PinWPS")) return network->wifi.pin_wps; return NULL; @@ -1938,16 +2386,20 @@ const char *connman_network_get_string(struct connman_network *network, * Set boolean value for specific key */ int connman_network_set_bool(struct connman_network *network, - const char *key, connman_bool_t value) + const char *key, bool value) { - DBG("network %p key %s value %d", network, key, value); - 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.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; } @@ -1959,21 +2411,51 @@ int connman_network_set_bool(struct connman_network *network, * * Get boolean value for specific key */ -connman_bool_t connman_network_get_bool(struct connman_network *network, +bool connman_network_get_bool(struct connman_network *network, const char *key) { - DBG("network %p key %s", network, key); - - if (g_str_equal(key, "Roaming") == TRUE) + if (g_str_equal(key, "Roaming")) return network->roaming; - else if (g_str_equal(key, "WiFi.WPS") == TRUE) + else if (g_str_equal(key, "WiFi.WPS")) return network->wifi.wps; - else if (g_str_equal(key, "WiFi.UseWPS") == TRUE) + 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; + return false; } +#if defined TIZEN_EXT +/** + * connman_network_set_vsie_list: + * @network: network structure + * @vsie_list: GSList pointer + * + * Set vendor specific list pointer + */ +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; +} + +/** + * connman_network_get_vsie_list: + * @network: network structure + * + * Get vendor specific list pointer + */ +void *connman_network_get_vsie_list(struct connman_network *network) +{ + return network->wifi.vsie_list; +} +#endif + /** * connman_network_set_blob: * @network: network structure @@ -1986,12 +2468,10 @@ connman_bool_t connman_network_get_bool(struct connman_network *network, int connman_network_set_blob(struct connman_network *network, const char *key, const void *data, unsigned int size) { - DBG("network %p key %s size %d", network, key, size); - - if (g_str_equal(key, "WiFi.SSID") == TRUE) { + if (g_str_equal(key, "WiFi.SSID")) { g_free(network->wifi.ssid); network->wifi.ssid = g_try_malloc(size); - if (network->wifi.ssid != NULL) { + if (network->wifi.ssid) { memcpy(network->wifi.ssid, data, size); network->wifi.ssid_len = size; } else @@ -2014,10 +2494,8 @@ 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) { - DBG("network %p key %s", network, key); - - if (g_str_equal(key, "WiFi.SSID") == TRUE) { - if (size != NULL) + if (g_str_equal(key, "WiFi.SSID")) { + if (size) *size = network->wifi.ssid_len; return network->wifi.ssid; } @@ -2031,12 +2509,12 @@ void __connman_network_set_device(struct connman_network *network, if (network->device == device) return; - if (network->device != NULL) + if (network->device) network_remove(network); network->device = device; - if (network->device != NULL) + if (network->device) network_probe(network); } @@ -2081,6 +2559,7 @@ void connman_network_update(struct connman_network *network) case CONNMAN_NETWORK_TYPE_VENDOR: return; case CONNMAN_NETWORK_TYPE_ETHERNET: + case CONNMAN_NETWORK_TYPE_GADGET: case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN: case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN: case CONNMAN_NETWORK_TYPE_CELLULAR: @@ -2088,7 +2567,7 @@ void connman_network_update(struct connman_network *network) break; } - if (network->group != NULL) + if (network->group) __connman_service_update_from_network(network); }