Add nameserver settings to the manual configuration setting
[framework/connectivity/connman.git] / src / network.c
index b059b82..74b104b 100644 (file)
@@ -91,8 +91,6 @@ static const char *type2string(enum connman_network_type type)
        case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
                return "bluetooth";
        case CONNMAN_NETWORK_TYPE_CELLULAR:
-       case CONNMAN_NETWORK_TYPE_MBM:
-       case CONNMAN_NETWORK_TYPE_HSO:
                return "cellular";
        }
 
@@ -239,7 +237,8 @@ static void unregister_interface(struct connman_element *element)
 
        network->registered = FALSE;
 
-       emit_networks_signal(network->device);
+       if (network->device != NULL)
+               emit_networks_signal(network->device);
 
        g_dbus_unregister_interface(connection, element->path,
                                                CONNMAN_NETWORK_INTERFACE);
@@ -315,6 +314,8 @@ static void network_destruct(struct connman_element *element)
                connman_ipconfig_unref(network->ipconfig);
                network->ipconfig = NULL;
        }
+
+       network->device = NULL;
 }
 
 /**
@@ -445,19 +446,31 @@ const char *connman_network_get_path(struct connman_network *network)
  */
 void connman_network_set_index(struct connman_network *network, int index)
 {
-       if (network->element.index < 0) {
-               struct connman_service *service;
+       struct connman_service *service;
+
+       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.
                 */
-               service = __connman_service_lookup_from_network(network);
-               if (service != NULL)
-                       __connman_service_create_ipconfig(service, index);
+               __connman_service_create_ipconfig(service, index);
+       else {
+               struct connman_ipconfig *ipconfig;
+
+               /* If index changed, the index of ipconfig must be reset. */
+               ipconfig = __connman_service_get_ipconfig(service);
+               if (ipconfig == NULL)
+                       goto done;
+
+               __connman_ipconfig_set_index(ipconfig, index);
        }
 
+done:
        network->element.index = index;
 }
 
@@ -515,8 +528,6 @@ void connman_network_set_group(struct connman_network *network,
        case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
        case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
        case CONNMAN_NETWORK_TYPE_CELLULAR:
-       case CONNMAN_NETWORK_TYPE_MBM:
-       case CONNMAN_NETWORK_TYPE_HSO:
        case CONNMAN_NETWORK_TYPE_WIFI:
        case CONNMAN_NETWORK_TYPE_WIMAX:
                break;
@@ -568,8 +579,6 @@ connman_bool_t __connman_network_get_weakness(struct connman_network *network)
        case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
        case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
        case CONNMAN_NETWORK_TYPE_CELLULAR:
-       case CONNMAN_NETWORK_TYPE_MBM:
-       case CONNMAN_NETWORK_TYPE_HSO:
        case CONNMAN_NETWORK_TYPE_WIMAX:
                break;
        case CONNMAN_NETWORK_TYPE_WIFI:
@@ -736,6 +745,7 @@ 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);
@@ -753,6 +763,13 @@ static void set_connected_manual(struct connman_network *network)
                return;
        }
 
+       connman_element_get_value(&network->element,
+                       CONNMAN_PROPERTY_ID_IPV4_NAMESERVER, &nameserver);
+       if (nameserver != NULL)
+               __connman_service_append_nameserver(service, nameserver);
+
+       __connman_ipconfig_set_gateway(ipconfig, &network->element);
+
        network->connecting = FALSE;
 
        connman_network_set_associating(network, FALSE);
@@ -982,6 +999,122 @@ 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)
+{
+       struct connman_service *service;
+       int err;
+
+       service = __connman_service_lookup_from_network(network);
+       if (service == NULL)
+               return -EINVAL;
+
+       err = __connman_ipconfig_set_address(ipconfig);
+       if (err < 0) {
+               connman_network_set_error(network,
+                       CONNMAN_NETWORK_ERROR_CONFIGURE_FAIL);
+               return err;
+       }
+
+       __connman_ipconfig_set_gateway(ipconfig, &network->element);
+
+       __connman_service_indicate_state(service, CONNMAN_SERVICE_STATE_READY);
+
+       return 0;
+}
+
+int __connman_network_clear_ipconfig(struct connman_network *network,
+                                       struct connman_ipconfig *ipconfig)
+{
+       struct connman_service *service;
+       enum connman_ipconfig_method method;
+
+       service = __connman_service_lookup_from_network(network);
+       if (service == NULL)
+               return -EINVAL;
+
+       method = __connman_ipconfig_get_method(ipconfig);
+
+       switch (method) {
+       case CONNMAN_IPCONFIG_METHOD_UNKNOWN:
+       case CONNMAN_IPCONFIG_METHOD_OFF:
+       case CONNMAN_IPCONFIG_METHOD_FIXED:
+               return -EINVAL;
+       case CONNMAN_IPCONFIG_METHOD_MANUAL:
+               connman_element_unregister_children_type(&network->element,
+                                       CONNMAN_ELEMENT_TYPE_CONNECTION);
+               __connman_ipconfig_clear_address(ipconfig);
+               break;
+       case CONNMAN_IPCONFIG_METHOD_DHCP:
+               dhcp_stop(network);
+               break;
+       }
+
+       __connman_service_indicate_state(service,
+                                       CONNMAN_SERVICE_STATE_CONFIGURATION);
+
+       return 0;
+}
+
+int __connman_network_set_ipconfig(struct connman_network *network, struct connman_ipconfig *ipconfig)
+{
+       enum connman_ipconfig_method method;
+
+       method = __connman_ipconfig_get_method(ipconfig);
+
+       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);
+       }
+
+       return 0;
+}
+
 /**
  * connman_network_set_address:
  * @network: network structure
@@ -1439,8 +1572,6 @@ static int network_probe(struct connman_element *element)
        case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
        case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
        case CONNMAN_NETWORK_TYPE_CELLULAR:
-       case CONNMAN_NETWORK_TYPE_MBM:
-       case CONNMAN_NETWORK_TYPE_HSO:
        case CONNMAN_NETWORK_TYPE_WIFI:
        case CONNMAN_NETWORK_TYPE_WIMAX:
                if (network->group != NULL)
@@ -1471,8 +1602,6 @@ static void network_remove(struct connman_element *element)
        case CONNMAN_NETWORK_TYPE_BLUETOOTH_PAN:
        case CONNMAN_NETWORK_TYPE_BLUETOOTH_DUN:
        case CONNMAN_NETWORK_TYPE_CELLULAR:
-       case CONNMAN_NETWORK_TYPE_MBM:
-       case CONNMAN_NETWORK_TYPE_HSO:
        case CONNMAN_NETWORK_TYPE_WIFI:
        case CONNMAN_NETWORK_TYPE_WIMAX:
                if (network->group != NULL) {