X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Fnetwork.c;h=1fa62ee400215fccb768cb18b668463c5b27c5eb;hb=6fd94b729495d6b9cdb66ae33adafd59f8b38957;hp=74b104b82964ace3adb69f0d137b94d6b0275d8a;hpb=9885b58b9ffbb880f2e77a1ce8462b7a9786e05d;p=framework%2Fconnectivity%2Fconnman.git diff --git a/src/network.c b/src/network.c index 74b104b..1fa62ee 100644 --- a/src/network.c +++ b/src/network.c @@ -26,8 +26,6 @@ #include #include -#include - #include "connman.h" static unsigned int hidden_counter = 0; @@ -35,7 +33,6 @@ static unsigned int hidden_counter = 0; struct connman_network { struct connman_element element; enum connman_network_type type; - enum connman_network_protocol protocol; connman_bool_t available; connman_bool_t connected; connman_bool_t roaming; @@ -43,16 +40,13 @@ struct connman_network { connman_uint8_t strength; connman_uint16_t frequency; char *identifier; - char *address; char *name; char *node; char *group; - struct connman_ipconfig *ipconfig; struct connman_network_driver *driver; void *driver_data; - connman_bool_t registered; connman_bool_t connecting; connman_bool_t associating; @@ -72,6 +66,9 @@ struct connman_network { char *private_key_path; char *private_key_passphrase; char *phase2_auth; + connman_bool_t wps; + connman_bool_t use_wps; + char *pin_wps; } wifi; }; @@ -97,159 +94,12 @@ static const char *type2string(enum connman_network_type type) return NULL; } -static DBusMessage *get_properties(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - struct connman_network *network = data; - DBusMessage *reply; - DBusMessageIter array, dict; - - DBG("conn %p", conn); - - if (__connman_security_check_privilege(msg, - CONNMAN_SECURITY_PRIVILEGE_PUBLIC) < 0) - return __connman_error_permission_denied(msg); - - reply = dbus_message_new_method_return(msg); - if (reply == NULL) - return NULL; - - dbus_message_iter_init_append(reply, &array); - - connman_dbus_dict_open(&array, &dict); - - if (network->device) { - const char *path = connman_device_get_path(network->device); - if (path != NULL) - connman_dbus_dict_append_basic(&dict, "Device", - DBUS_TYPE_OBJECT_PATH, &path); - } - - if (network->address != NULL) - connman_dbus_dict_append_basic(&dict, "Address", - DBUS_TYPE_STRING, &network->address); - - if (network->name != NULL) - connman_dbus_dict_append_basic(&dict, "Name", - DBUS_TYPE_STRING, &network->name); - - connman_dbus_dict_append_basic(&dict, "Connected", - DBUS_TYPE_BOOLEAN, &network->connected); - - if (network->strength > 0) - connman_dbus_dict_append_basic(&dict, "Strength", - DBUS_TYPE_BYTE, &network->strength); - - if (network->frequency > 0) - connman_dbus_dict_append_basic(&dict, "Frequency", - DBUS_TYPE_UINT16, &network->frequency); - - if (network->wifi.ssid != NULL && network->wifi.ssid_len > 0) - connman_dbus_dict_append_fixed_array(&dict, "WiFi.SSID", - DBUS_TYPE_BYTE, &network->wifi.ssid, - network->wifi.ssid_len); - - if (network->wifi.mode != NULL) - connman_dbus_dict_append_basic(&dict, "WiFi.Mode", - DBUS_TYPE_STRING, &network->wifi.mode); - - if (network->wifi.channel > 0) - connman_dbus_dict_append_basic(&dict, "WiFi.Channel", - DBUS_TYPE_UINT16, &network->wifi.channel); - - if (network->wifi.security != NULL) { - connman_dbus_dict_append_basic(&dict, "WiFi.Security", - DBUS_TYPE_STRING, &network->wifi.security); - - if (g_strcmp0(network->wifi.security, "ieee8021x") == 0 && - network->wifi.eap != NULL) - connman_dbus_dict_append_basic(&dict, "WiFi.EAP", - DBUS_TYPE_STRING, &network->wifi.eap); - } - - - if (network->wifi.passphrase != NULL && - __connman_security_check_privilege(msg, - CONNMAN_SECURITY_PRIVILEGE_SECRET) == 0) - connman_dbus_dict_append_basic(&dict, "WiFi.Passphrase", - DBUS_TYPE_STRING, &network->wifi.passphrase); - - connman_dbus_dict_close(&array, &dict); - - return reply; -} - -static GDBusMethodTable network_methods[] = { - { "GetProperties", "", "a{sv}", get_properties }, - { }, -}; - -static GDBusSignalTable network_signals[] = { - { "PropertyChanged", "sv" }, - { }, -}; - -static DBusConnection *connection; - -static void append_networks(DBusMessageIter *iter, void *user_data) -{ - struct connman_device *device = user_data; - - __connman_element_list((struct connman_element *) device, - CONNMAN_ELEMENT_TYPE_NETWORK, iter); -} - -static void emit_networks_signal(struct connman_device *device) -{ - const char *path = connman_device_get_path(device); - - connman_dbus_property_changed_array(path, - CONNMAN_DEVICE_INTERFACE, "Networks", - DBUS_TYPE_OBJECT_PATH, append_networks, device); -} - -static int register_interface(struct connman_element *element) -{ - struct connman_network *network = element->network; - - DBG("element %p name %s", element, element->name); - - if (g_dbus_register_interface(connection, element->path, - CONNMAN_NETWORK_INTERFACE, - network_methods, network_signals, - NULL, network, NULL) == FALSE) { - connman_error("Failed to register %s network", element->path); - return -EIO; - } - - network->registered = TRUE; - - emit_networks_signal(network->device); - - return 0; -} - -static void unregister_interface(struct connman_element *element) -{ - struct connman_network * network = element->network; - - DBG("element %p name %s", element, element->name); - - network->registered = FALSE; - - if (network->device != NULL) - emit_networks_signal(network->device); - - g_dbus_unregister_interface(connection, element->path, - CONNMAN_NETWORK_INTERFACE); -} - connman_bool_t __connman_network_has_driver(struct connman_network *network) { if (network == NULL || network->driver == NULL) return FALSE; - return network->registered; + return TRUE; } static GSList *driver_list = NULL; @@ -272,8 +122,18 @@ static gint compare_priority(gconstpointer a, gconstpointer b) */ int connman_network_driver_register(struct connman_network_driver *driver) { + GSList *list; + DBG("driver %p name %s", driver, driver->name); + for (list = driver_list; list; list = list->next) { + struct connman_network_driver *tmp = list->data; + + if (tmp->type == driver->type) + return -EALREADY; + + } + driver_list = g_slist_insert_sorted(driver_list, driver, compare_priority); @@ -303,18 +163,20 @@ static void network_destruct(struct connman_element *element) g_free(network->wifi.mode); g_free(network->wifi.security); g_free(network->wifi.passphrase); + g_free(network->wifi.eap); + g_free(network->wifi.identity); + g_free(network->wifi.ca_cert_path); + 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); g_free(network->group); g_free(network->node); g_free(network->name); - g_free(network->address); g_free(network->identifier); - if (network->ipconfig) { - connman_ipconfig_unref(network->ipconfig); - network->ipconfig = NULL; - } - network->device = NULL; } @@ -344,7 +206,6 @@ struct connman_network *connman_network_create(const char *identifier, __connman_element_initialize(&network->element); - //temp = connman_dbus_encode_string(identifier); if (identifier == NULL) { temp = g_strdup_printf("hidden_%d", hidden_counter++); network->hidden = TRUE; @@ -427,17 +288,6 @@ const char *connman_network_get_identifier(struct connman_network *network) } /** - * connman_network_get_path: - * @network: network structure - * - * Get path name of network - */ -const char *connman_network_get_path(struct connman_network *network) -{ - return network->element.path; -} - -/** * connman_network_set_index: * @network: network structure * @index: index number @@ -447,23 +297,32 @@ const char *connman_network_get_path(struct connman_network *network) void connman_network_set_index(struct connman_network *network, int index) { struct connman_service *service; + struct connman_ipconfig *ipconfig; service = __connman_service_lookup_from_network(network); if (service == NULL) goto done; - if (network->element.index < 0) - /* - * This is needed for plugins that havent set their ipconfig - * layer yet, due to not being able to get a network index - * prior to creating a service. - */ - __connman_service_create_ipconfig(service, index); - else { - struct connman_ipconfig *ipconfig; + ipconfig = __connman_service_get_ip4config(service); + DBG("index %d service %p ip4config %p", network->element.index, + service, ipconfig); + + if (network->element.index < 0 && ipconfig == NULL) { + + ipconfig = __connman_service_get_ip4config(service); + if (ipconfig == NULL) + /* + * This is needed for plugins that havent set their + * ipconfig layer yet, due to not being able to get + * a network index prior to creating a service. + */ + __connman_service_create_ip4config(service, index); + else + __connman_ipconfig_set_index(ipconfig, index); + + } else { /* If index changed, the index of ipconfig must be reset. */ - ipconfig = __connman_service_get_ipconfig(service); if (ipconfig == NULL) goto done; @@ -498,19 +357,6 @@ struct connman_element *connman_network_get_element( } /** - * connman_network_set_protocol: - * @network: network structure - * @protocol: network protocol - * - * Change protocol of network - */ -void connman_network_set_protocol(struct connman_network *network, - enum connman_network_protocol protocol) -{ - network->protocol = protocol; -} - -/** * connman_network_set_group: * @network: network structure * @group: group name @@ -535,12 +381,12 @@ void connman_network_set_group(struct connman_network *network, if (g_strcmp0(network->group, group) == 0) { if (group != NULL) - __connman_profile_update_network(network); + __connman_service_update_from_network(network); return; } if (network->group != NULL) { - __connman_profile_remove_network(network); + __connman_service_remove_from_network(network); g_free(network->group); } @@ -548,7 +394,7 @@ void connman_network_set_group(struct connman_network *network, network->group = g_strdup(group); if (network->group != NULL) - __connman_profile_add_network(network); + __connman_service_create_from_network(network); } /** @@ -567,7 +413,7 @@ const char *__connman_network_get_ident(struct connman_network *network) if (network->device == NULL) return NULL; - return __connman_device_get_ident(network->device); + return connman_device_get_ident(network->device); } connman_bool_t __connman_network_get_weakness(struct connman_network *network) @@ -592,7 +438,7 @@ connman_bool_t __connman_network_get_weakness(struct connman_network *network) return FALSE; } -connman_bool_t __connman_network_get_connecting(struct connman_network *network) +connman_bool_t connman_network_get_connecting(struct connman_network *network) { return network->connecting; } @@ -653,7 +499,8 @@ int connman_network_set_associating(struct connman_network *network, service = __connman_service_lookup_from_network(network); __connman_service_indicate_state(service, - CONNMAN_SERVICE_STATE_ASSOCIATION); + CONNMAN_SERVICE_STATE_ASSOCIATION, + CONNMAN_IPCONFIG_TYPE_IPV4); } return 0; @@ -671,7 +518,8 @@ static void set_associate_error(struct connman_network *network) service = __connman_service_lookup_from_network(network); __connman_service_indicate_state(service, - CONNMAN_SERVICE_STATE_FAILURE); + CONNMAN_SERVICE_STATE_FAILURE, + CONNMAN_IPCONFIG_TYPE_IPV4); } static void set_configure_error(struct connman_network *network) @@ -683,22 +531,58 @@ static void set_configure_error(struct connman_network *network) service = __connman_service_lookup_from_network(network); __connman_service_indicate_state(service, - CONNMAN_SERVICE_STATE_FAILURE); + CONNMAN_SERVICE_STATE_FAILURE, + CONNMAN_IPCONFIG_TYPE_IPV4); +} + +static void set_invalid_key_error(struct connman_network *network) +{ + struct connman_service *service; + + service = __connman_service_lookup_from_network(network); + + __connman_service_indicate_error(service, + CONNMAN_SERVICE_ERROR_INVALID_KEY); } -void connman_network_set_method(struct connman_network *network, +static void set_connect_error(struct connman_network *network) +{ + struct connman_service *service; + + service = __connman_service_lookup_from_network(network); + + __connman_service_indicate_error(service, + CONNMAN_SERVICE_ERROR_CONNECT_FAILED); +} + +void connman_network_set_ipv4_method(struct connman_network *network, enum connman_ipconfig_method method) { struct connman_service *service; struct connman_ipconfig *ipconfig; - network->element.ipv4.method = method; + service = __connman_service_lookup_from_network(network); + if (service == NULL) + return; + + ipconfig = __connman_service_get_ip4config(service); + if (ipconfig == NULL) + return; + + connman_ipconfig_set_method(ipconfig, method); +} + +void connman_network_set_ipv6_method(struct connman_network *network, + enum connman_ipconfig_method method) +{ + struct connman_service *service; + struct connman_ipconfig *ipconfig; service = __connman_service_lookup_from_network(network); if (service == NULL) return; - ipconfig = __connman_service_get_ipconfig(service); + ipconfig = __connman_service_get_ip6config(service); if (ipconfig == NULL) return; @@ -721,9 +605,31 @@ void connman_network_set_error(struct connman_network *network, case CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL: set_configure_error(network); break; + case CONNMAN_NETWORK_ERROR_INVALID_KEY: + set_invalid_key_error(network); + break; + case CONNMAN_NETWORK_ERROR_CONNECT_FAIL: + set_connect_error(network); + break; } } +void connman_network_clear_error(struct connman_network *network) +{ + struct connman_service *service; + + DBG("network %p", network); + + if (network == NULL) + return; + + if (network->connecting == TRUE || network->associating == TRUE) + return; + + service = __connman_service_lookup_from_network(network); + __connman_service_clear_error(service); +} + static void set_configuration(struct connman_network *network) { struct connman_service *service; @@ -738,95 +644,262 @@ static void set_configuration(struct connman_network *network) service = __connman_service_lookup_from_network(network); __connman_service_indicate_state(service, - CONNMAN_SERVICE_STATE_CONFIGURATION); + CONNMAN_SERVICE_STATE_CONFIGURATION, + CONNMAN_IPCONFIG_TYPE_IPV4); +} + +static void dhcp_success(struct connman_network *network) +{ + struct connman_service *service; + struct connman_ipconfig *ipconfig_ipv4; + int err; + + service = __connman_service_lookup_from_network(network); + if (service == NULL) + goto err; + + connman_network_set_associating(network, FALSE); + + network->connecting = FALSE; + + ipconfig_ipv4 = __connman_service_get_ip4config(service); + err = __connman_ipconfig_address_add(ipconfig_ipv4); + if (err < 0) + goto err; + + err = __connman_ipconfig_gateway_add(ipconfig_ipv4); + if (err < 0) + goto err; + + __connman_service_set_ipconfig_ready(service, CONNMAN_IPCONFIG_TYPE_IPV4); + + return; + +err: + connman_network_set_error(network, + CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); +} + +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) + return; + + ipconfig_ipv4 = __connman_service_get_ip4config(service); + __connman_ipconfig_address_remove(ipconfig_ipv4); + + __connman_service_indicate_state(service, CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV4); +} + +static void dhcp_callback(struct connman_network *network, + connman_bool_t success) +{ + DBG("success %d", success); + + if (success == TRUE) + 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); + + 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; + + __connman_service_set_ipconfig_ready(service, CONNMAN_IPCONFIG_TYPE_IPV4); + + return 0; + +err: + connman_network_set_error(network, + CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); + + return err; } static void set_connected_manual(struct connman_network *network) { struct connman_service *service; struct connman_ipconfig *ipconfig; - const char *nameserver = NULL; int err; DBG("network %p", network); service = __connman_service_lookup_from_network(network); - ipconfig = __connman_service_get_ipconfig(service); + ipconfig = __connman_service_get_ip4config(service); set_configuration(network); - err = __connman_ipconfig_set_address(ipconfig); - if (err < 0) { - connman_network_set_error(network, - CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); - return; - } - - connman_element_get_value(&network->element, - CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver); - if (nameserver != NULL) - __connman_service_append_nameserver(service, nameserver); + err = __connman_ipconfig_address_add(ipconfig); + if (err < 0) + goto err; - __connman_ipconfig_set_gateway(ipconfig, &network->element); + err = __connman_ipconfig_gateway_add(ipconfig); + if (err < 0) + goto err; network->connecting = FALSE; connman_network_set_associating(network, FALSE); - __connman_service_indicate_state(service, CONNMAN_SERVICE_STATE_READY); + __connman_service_set_ipconfig_ready(service, CONNMAN_IPCONFIG_TYPE_IPV4); + + return; + +err: + connman_network_set_error(network, + CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); + return; } static int set_connected_dhcp(struct connman_network *network) { - struct connman_element *element; - int error; + int err; DBG("network %p", network); - if (network->protocol != CONNMAN_NETWORK_PROTOCOL_IP) - return -EINVAL; + set_configuration(network); + + err = __connman_dhcp_start(network, dhcp_callback); + if (err < 0) { + connman_error("Can not request DHCP lease"); + return err; + } + + return 0; +} - element = connman_element_create(NULL); - if (element == NULL) - return -ENOMEM; +static int manual_ipv6_set(struct connman_network *network, + struct connman_ipconfig *ipconfig_ipv6) +{ + struct connman_service *service; + int err; - element->type = CONNMAN_ELEMENT_TYPE_DHCP; - element->index = network->element.index; + service = __connman_service_lookup_from_network(network); + if (service == NULL) + return -EINVAL; - error = connman_element_register(element, &network->element); - if (error < 0) { - connman_element_unref(element); - return error; + err = __connman_ipconfig_address_add(ipconfig_ipv6); + if (err < 0) { + connman_network_set_error(network, + CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); + return err; } - set_configuration(network); + /* + * READY state will be indicated by IPV4 setting + * gateway will be set by IPV4 setting + */ return 0; } +static void autoconf_ipv6_set(struct connman_network *network) +{ + struct connman_service *service; + + DBG("network %p", network); + + service = __connman_service_lookup_from_network(network); + + __connman_device_increase_connections(network->device); + + __connman_device_set_network(network->device, network); + + connman_device_set_disconnected(network->device, FALSE); + + /* XXX: Append IPv6 nameservers here */ + + network->connecting = FALSE; + + __connman_service_set_ipconfig_ready(service, CONNMAN_IPCONFIG_TYPE_IPV6); +} + static gboolean set_connected(gpointer user_data) { struct connman_network *network = user_data; struct connman_service *service; - struct connman_ipconfig *ipconfig; - enum connman_ipconfig_method method; + struct connman_ipconfig *ipconfig_ipv4, *ipconfig_ipv6; + enum connman_ipconfig_method ipv4_method, ipv6_method; service = __connman_service_lookup_from_network(network); - ipconfig = __connman_service_get_ipconfig(service); + ipconfig_ipv4 = __connman_service_get_ip4config(service); + ipconfig_ipv6 = __connman_service_get_ip6config(service); - method = __connman_ipconfig_get_method(ipconfig); + 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 %d", method); + DBG("method ipv4 %d ipv6 %d", ipv4_method, ipv6_method); + DBG("network connected %d", network->connected); if (network->connected == TRUE) { - switch (method) { + int ret; + + switch (ipv6_method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: - return FALSE; + break; + 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 FALSE; + } + break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + break; + } + + switch (ipv4_method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + case CONNMAN_IPCONFIG_METHOD_AUTO: + return FALSE; case CONNMAN_IPCONFIG_METHOD_FIXED: + if (set_connected_fixed(network) < 0) { + connman_network_set_error(network, + CONNMAN_NETWORK_ERROR_ASSOCIATE_FAIL); + return FALSE; + } + return TRUE; + case CONNMAN_IPCONFIG_METHOD_MANUAL: set_connected_manual(network); return TRUE; case CONNMAN_IPCONFIG_METHOD_DHCP: @@ -845,12 +918,25 @@ static gboolean set_connected(gpointer user_data) __connman_device_set_network(network->device, NULL); network->hidden = FALSE; - __connman_device_decrease_connections(network->device); - service = __connman_service_lookup_from_network(network); __connman_service_indicate_state(service, - CONNMAN_SERVICE_STATE_IDLE); + CONNMAN_SERVICE_STATE_DISCONNECT, + CONNMAN_IPCONFIG_TYPE_IPV4); + + __connman_service_indicate_state(service, + CONNMAN_SERVICE_STATE_DISCONNECT, + CONNMAN_IPCONFIG_TYPE_IPV6); + + __connman_connection_gateway_remove(service); + + __connman_service_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV4); + + __connman_service_indicate_state(service, + CONNMAN_SERVICE_STATE_IDLE, + CONNMAN_IPCONFIG_TYPE_IPV6); } network->connecting = FALSE; @@ -874,24 +960,18 @@ int connman_network_set_connected(struct connman_network *network, if ((network->connecting == TRUE || network->associating == TRUE) && connected == FALSE) { - connman_element_set_error(&network->element, - CONNMAN_ELEMENT_ERROR_CONNECT_FAILED); + connman_network_set_error(network, + CONNMAN_NETWORK_ERROR_CONNECT_FAIL); __connman_network_disconnect(network); } if (network->connected == connected) return -EALREADY; - network->connected = connected; - - if (network->registered == FALSE) { - g_idle_add(set_connected, network); - return 0; - } + if (connected == FALSE) + __connman_device_decrease_connections(network->device); - connman_dbus_property_changed_basic(network->element.path, - CONNMAN_NETWORK_INTERFACE, "Connected", - DBUS_TYPE_BOOLEAN, &connected); + network->connected = connected; set_connected(network); @@ -944,10 +1024,13 @@ int __connman_network_connect(struct connman_network *network) if (network->driver->connect == NULL) return -ENOSYS; - __connman_device_disconnect(network->device); + if (network->device == NULL) + return -ENODEV; network->connecting = TRUE; + __connman_device_disconnect(network->device); + err = network->driver->connect(network); if (err < 0) { if (err == -EINPROGRESS) @@ -999,45 +1082,6 @@ int __connman_network_disconnect(struct connman_network *network) return err; } -static int dhcp_start(struct connman_network *network) -{ - struct connman_element *element; - int error; - - if (network->protocol != CONNMAN_NETWORK_PROTOCOL_IP) - return -EINVAL; - - element = connman_element_create(NULL); - if (element == NULL) - return -ENOMEM; - - element->type = CONNMAN_ELEMENT_TYPE_DHCP; - element->index = network->element.index; - - error = connman_element_register(element, &network->element); - if (error < 0) { - connman_element_unref(element); - return error; - } - - return 0; -} - -static int dhcp_stop(struct connman_network *network) -{ - if (network->protocol != CONNMAN_NETWORK_PROTOCOL_IP) - return -EINVAL; - - connman_element_unregister_children_type(&network->element, - CONNMAN_ELEMENT_TYPE_CONNECTION); - connman_element_unregister_children_type(&network->element, - CONNMAN_ELEMENT_TYPE_IPV4); - connman_element_unregister_children_type(&network->element, - CONNMAN_ELEMENT_TYPE_DHCP); - - return 0; -} - static int manual_ipv4_set(struct connman_network *network, struct connman_ipconfig *ipconfig) { @@ -1048,16 +1092,16 @@ static int manual_ipv4_set(struct connman_network *network, if (service == NULL) return -EINVAL; - err = __connman_ipconfig_set_address(ipconfig); + err = __connman_ipconfig_address_add(ipconfig); if (err < 0) { connman_network_set_error(network, CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL); return err; } - __connman_ipconfig_set_gateway(ipconfig, &network->element); + __connman_ipconfig_gateway_add(ipconfig); - __connman_service_indicate_state(service, CONNMAN_SERVICE_STATE_READY); + __connman_service_set_ipconfig_ready(service, CONNMAN_IPCONFIG_TYPE_IPV4); return 0; } @@ -1067,84 +1111,174 @@ int __connman_network_clear_ipconfig(struct connman_network *network, { struct connman_service *service; enum connman_ipconfig_method method; + enum connman_ipconfig_type type; service = __connman_service_lookup_from_network(network); if (service == NULL) return -EINVAL; method = __connman_ipconfig_get_method(ipconfig); + type = __connman_ipconfig_get_config_type(ipconfig); switch (method) { case CONNMAN_IPCONFIG_METHOD_UNKNOWN: case CONNMAN_IPCONFIG_METHOD_OFF: case CONNMAN_IPCONFIG_METHOD_FIXED: + case CONNMAN_IPCONFIG_METHOD_AUTO: return -EINVAL; case CONNMAN_IPCONFIG_METHOD_MANUAL: - connman_element_unregister_children_type(&network->element, - CONNMAN_ELEMENT_TYPE_CONNECTION); - __connman_ipconfig_clear_address(ipconfig); + __connman_ipconfig_address_remove(ipconfig); break; case CONNMAN_IPCONFIG_METHOD_DHCP: - dhcp_stop(network); + __connman_dhcp_stop(network); break; } - __connman_service_indicate_state(service, - CONNMAN_SERVICE_STATE_CONFIGURATION); + if (type == CONNMAN_IPCONFIG_TYPE_IPV6) + __connman_service_indicate_state(service, + CONNMAN_SERVICE_STATE_CONFIGURATION, + CONNMAN_IPCONFIG_TYPE_IPV6); + else if (type == CONNMAN_IPCONFIG_TYPE_IPV4) + __connman_service_indicate_state(service, + CONNMAN_SERVICE_STATE_CONFIGURATION, + CONNMAN_IPCONFIG_TYPE_IPV4); return 0; } -int __connman_network_set_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig) +int __connman_network_set_ipconfig(struct connman_network *network, + struct connman_ipconfig *ipconfig_ipv4, + struct connman_ipconfig *ipconfig_ipv6) { enum connman_ipconfig_method method; + int ret; - method = __connman_ipconfig_get_method(ipconfig); + if (ipconfig_ipv6) { + method = __connman_ipconfig_get_method(ipconfig_ipv6); - switch (method) { - case CONNMAN_IPCONFIG_METHOD_UNKNOWN: - case CONNMAN_IPCONFIG_METHOD_OFF: - case CONNMAN_IPCONFIG_METHOD_FIXED: - return -EINVAL; - case CONNMAN_IPCONFIG_METHOD_MANUAL: - return manual_ipv4_set(network, ipconfig); - case CONNMAN_IPCONFIG_METHOD_DHCP: - return dhcp_start(network); + switch (method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + break; + 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 ret; + } + break; + case CONNMAN_IPCONFIG_METHOD_DHCP: + break; + } + } + + if (ipconfig_ipv4) { + method = __connman_ipconfig_get_method(ipconfig_ipv4); + + switch (method) { + case CONNMAN_IPCONFIG_METHOD_UNKNOWN: + case CONNMAN_IPCONFIG_METHOD_OFF: + case CONNMAN_IPCONFIG_METHOD_FIXED: + case CONNMAN_IPCONFIG_METHOD_AUTO: + return -EINVAL; + case CONNMAN_IPCONFIG_METHOD_MANUAL: + return manual_ipv4_set(network, ipconfig_ipv4); + case CONNMAN_IPCONFIG_METHOD_DHCP: + return __connman_dhcp_start(network, dhcp_callback); + } } return 0; } -/** - * connman_network_set_address: - * @network: network structure - * @address: binary address value - * @size: binary address length - * - * Set unique address value for network - */ -int connman_network_set_address(struct connman_network *network, - const void *address, unsigned int size) +int connman_network_set_ipaddress(struct connman_network *network, + struct connman_ipaddress *ipaddress) +{ + struct connman_service *service; + struct connman_ipconfig *ipconfig = NULL; + + DBG("network %p", network); + + service = __connman_service_lookup_from_network(network); + if (service == NULL) + return -EINVAL; + + ipconfig = __connman_service_get_ipconfig(service, ipaddress->family); + if (ipconfig == NULL) + return -EINVAL; + + __connman_ipconfig_set_local(ipconfig, ipaddress->local); + __connman_ipconfig_set_peer(ipconfig, ipaddress->peer); + __connman_ipconfig_set_broadcast(ipconfig, ipaddress->broadcast); + __connman_ipconfig_set_prefixlen(ipconfig, ipaddress->prefixlen); + __connman_ipconfig_set_gateway(ipconfig, ipaddress->gateway); + + return 0; +} + +int connman_network_set_pac(struct connman_network *network, + const char *pac) +{ + struct connman_service *service; + + DBG("network %p pac %s", network, pac); + + service = __connman_service_lookup_from_network(network); + if (service == NULL) + return -EINVAL; + + __connman_service_set_pac(service, pac); + + return 0; +} + +int connman_network_set_nameservers(struct connman_network *network, + const char *nameservers) { - const unsigned char *addr_octet = address; - char *str; + struct connman_service *service; + char **nameservers_array = NULL; + int i; - DBG("network %p size %d", network, size); + DBG("network %p nameservers %s", network, nameservers); - if (size != 6) + service = __connman_service_lookup_from_network(network); + if (service == NULL) return -EINVAL; - str = g_strdup_printf("%02X:%02X:%02X:%02X:%02X:%02X", - addr_octet[0], addr_octet[1], addr_octet[2], - addr_octet[3], addr_octet[4], addr_octet[5]); - if (str == NULL) - return -ENOMEM; + __connman_service_nameserver_clear(service); - g_free(network->address); - network->address = str; + if (nameservers != NULL) + nameservers_array = g_strsplit(nameservers, " ", 0); - return connman_element_set_string(&network->element, - "Address", network->address); + for (i = 0; nameservers_array[i] != NULL; i++) { + __connman_service_nameserver_append(service, + nameservers_array[i]); + } + + g_strfreev(nameservers_array); + + return 0; +} + +int connman_network_set_domain(struct connman_network *network, + const char *domain) +{ + struct connman_service *service; + + DBG("network %p domain %s", network, domain); + + service = __connman_service_lookup_from_network(network); + if (service == NULL) + return -EINVAL; + + __connman_service_set_domainname(service, domain); + + return 0; } /** @@ -1219,10 +1353,7 @@ int connman_network_set_string(struct connman_network *network, if (g_strcmp0(key, "Name") == 0) return connman_network_set_name(network, value); - if (g_str_equal(key, "Address") == TRUE) { - g_free(network->address); - network->address = g_strdup(value); - } else if (g_str_equal(key, "Node") == TRUE) { + if (g_str_equal(key, "Node") == TRUE) { g_free(network->node); network->node = g_strdup(value); } else if (g_str_equal(key, "WiFi.Mode") == TRUE) { @@ -1255,6 +1386,9 @@ int connman_network_set_string(struct connman_network *network, } else if (g_str_equal(key, "WiFi.Phase2") == TRUE) { g_free(network->wifi.phase2_auth); network->wifi.phase2_auth = g_strdup(value); + } else if (g_str_equal(key, "WiFi.PinWPS") == TRUE) { + g_free(network->wifi.pin_wps); + network->wifi.pin_wps = g_strdup(value); } err = connman_element_set_string(&network->element, key, value); @@ -1282,9 +1416,7 @@ const char *connman_network_get_string(struct connman_network *network, { DBG("network %p key %s", network, key); - if (g_str_equal(key, "Address") == TRUE) - return network->address; - else if (g_str_equal(key, "Name") == TRUE) + if (g_str_equal(key, "Name") == TRUE) return network->name; else if (g_str_equal(key, "Node") == TRUE) return network->node; @@ -1308,6 +1440,8 @@ const char *connman_network_get_string(struct connman_network *network, return network->wifi.private_key_passphrase; else if (g_str_equal(key, "WiFi.Phase2") == TRUE) return network->wifi.phase2_auth; + else if (g_str_equal(key, "WiFi.PinWPS") == TRUE) + return network->wifi.pin_wps; return connman_element_get_string(&network->element, key); } @@ -1327,6 +1461,10 @@ int connman_network_set_bool(struct connman_network *network, if (g_strcmp0(key, "Roaming") == 0) return connman_network_set_roaming(network, 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; return connman_element_set_bool(&network->element, key, value); } @@ -1345,6 +1483,10 @@ connman_bool_t connman_network_get_bool(struct connman_network *network, if (g_str_equal(key, "Roaming") == TRUE) return network->roaming; + else if (g_str_equal(key, "WiFi.WPS") == TRUE) + return network->wifi.wps; + else if (g_str_equal(key, "WiFi.UseWPS") == TRUE) + return network->wifi.use_wps; return connman_element_get_bool(&network->element, key); } @@ -1441,9 +1583,6 @@ int connman_network_set_blob(struct connman_network *network, { DBG("network %p key %s size %d", network, key, size); - if (g_strcmp0(key, "Address") == 0) - return connman_network_set_address(network, data, size); - if (g_str_equal(key, "WiFi.SSID") == TRUE) { g_free(network->wifi.ssid); network->wifi.ssid = g_try_malloc(size); @@ -1519,6 +1658,27 @@ void connman_network_set_data(struct connman_network *network, void *data) network->driver_data = data; } +void connman_network_update(struct connman_network *network) +{ + switch (network->type) { + case CONNMAN_NETWORK_TYPE_UNKNOWN: + case CONNMAN_NETWORK_TYPE_VENDOR: + return; + case CONNMAN_NETWORK_TYPE_ETHERNET: + case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN: + case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN: + case CONNMAN_NETWORK_TYPE_CELLULAR: + case CONNMAN_NETWORK_TYPE_WIFI: + case CONNMAN_NETWORK_TYPE_WIMAX: + break; + } + + if (network->group != NULL) + __connman_service_update_from_network(network); + + return; +} + static gboolean match_driver(struct connman_network *network, struct connman_network_driver *driver) { @@ -1533,7 +1693,6 @@ static int network_probe(struct connman_element *element) { struct connman_network *network = element->network; GSList *list; - int err; DBG("element %p name %s", element, element->name); @@ -1557,13 +1716,6 @@ static int network_probe(struct connman_element *element) if (network->driver == NULL) return -ENODEV; - err = register_interface(element); - if (err < 0) { - if (network->driver->remove) - network->driver->remove(network); - return err; - } - switch (network->type) { case CONNMAN_NETWORK_TYPE_UNKNOWN: case CONNMAN_NETWORK_TYPE_VENDOR: @@ -1574,9 +1726,9 @@ static int network_probe(struct connman_element *element) case CONNMAN_NETWORK_TYPE_CELLULAR: case CONNMAN_NETWORK_TYPE_WIFI: case CONNMAN_NETWORK_TYPE_WIMAX: - if (network->group != NULL) - __connman_profile_add_network(network); - break; + if (network->group != NULL && + __connman_service_create_from_network(network) == NULL) + return -EINVAL; } return 0; @@ -1605,7 +1757,7 @@ static void network_remove(struct connman_element *element) case CONNMAN_NETWORK_TYPE_WIFI: case CONNMAN_NETWORK_TYPE_WIMAX: if (network->group != NULL) { - __connman_profile_remove_network(network); + __connman_service_remove_from_network(network); g_free(network->group); network->group = NULL; @@ -1613,8 +1765,6 @@ static void network_remove(struct connman_element *element) break; } - unregister_interface(element); - if (network->driver->remove) network->driver->remove(network); } @@ -1628,9 +1778,6 @@ static void network_change(struct connman_element *element) if (element->state != CONNMAN_ELEMENT_STATE_ERROR) return; - if (element->error != CONNMAN_ELEMENT_ERROR_DHCP_FAILED) - return; - if (network->connected == FALSE) return; @@ -1659,8 +1806,6 @@ int __connman_network_init(void) { DBG(""); - connection = connman_dbus_get_connection(); - return connman_driver_register(&network_driver); } @@ -1669,6 +1814,4 @@ void __connman_network_cleanup(void) DBG(""); connman_driver_unregister(&network_driver); - - dbus_connection_unref(connection); }