element: Remove vendor code
[framework/connectivity/connman.git] / src / element.c
index faaa9f8..26c8a6e 100644 (file)
@@ -36,8 +36,8 @@ static DBusConnection *connection;
 
 static GNode *element_root = NULL;
 static GSList *driver_list = NULL;
-static gchar *device_filter = NULL;
-static gchar *nodevice_filter = NULL;
+static gchar **device_filter = NULL;
+static gchar **nodevice_filter = NULL;
 
 static gboolean started = FALSE;
 
@@ -48,28 +48,12 @@ static const char *type2string(enum connman_element_type type)
                return "unknown";
        case CONNMAN_ELEMENT_TYPE_ROOT:
                return "root";
-       case CONNMAN_ELEMENT_TYPE_PROFILE:
-               return "profile";
        case CONNMAN_ELEMENT_TYPE_DEVICE:
                return "device";
        case CONNMAN_ELEMENT_TYPE_NETWORK:
                return "network";
        case CONNMAN_ELEMENT_TYPE_SERVICE:
                return "service";
-       case CONNMAN_ELEMENT_TYPE_IPV4:
-               return "ipv4";
-       case CONNMAN_ELEMENT_TYPE_IPV6:
-               return "ipv6";
-       case CONNMAN_ELEMENT_TYPE_DHCP:
-               return "dhcp";
-       case CONNMAN_ELEMENT_TYPE_BOOTP:
-               return "bootp";
-       case CONNMAN_ELEMENT_TYPE_ZEROCONF:
-               return "zeroconf";
-       case CONNMAN_ELEMENT_TYPE_CONNECTION:
-               return "connection";
-       case CONNMAN_ELEMENT_TYPE_VENDOR:
-               return "vendor";
        }
 
        return NULL;
@@ -176,7 +160,7 @@ void __connman_element_list(struct connman_element *element,
                                                append_path, &filter);
 }
 
-static struct connman_network *__connman_element_get_network(struct connman_element *element)
+static struct connman_network *get_network(struct connman_element *element)
 {
        if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
                                                element->network != NULL)
@@ -185,7 +169,7 @@ static struct connman_network *__connman_element_get_network(struct connman_elem
        if (element->parent == NULL)
                return NULL;
 
-       return __connman_element_get_network(element->parent);
+       return get_network(element->parent);
 }
 
 struct connman_service *__connman_element_get_service(struct connman_element *element)
@@ -196,8 +180,11 @@ struct connman_service *__connman_element_get_service(struct connman_element *el
        enum connman_device_type type;
 
        device = __connman_element_get_device(element);
-       if (device == NULL)
-               return NULL;
+       if (device == NULL) {
+               /* Workaround for the connection removal. */
+               service = __connman_service_lookup_from_index(element->index);
+               return service;
+       }
 
        type = connman_device_get_type(device);
 
@@ -205,13 +192,14 @@ struct connman_service *__connman_element_get_service(struct connman_element *el
        case CONNMAN_DEVICE_TYPE_UNKNOWN:
        case CONNMAN_DEVICE_TYPE_VENDOR:
        case CONNMAN_DEVICE_TYPE_GPS:
+       case CONNMAN_DEVICE_TYPE_GADGET:
                break;
        case CONNMAN_DEVICE_TYPE_ETHERNET:
        case CONNMAN_DEVICE_TYPE_WIFI:
        case CONNMAN_DEVICE_TYPE_WIMAX:
        case CONNMAN_DEVICE_TYPE_BLUETOOTH:
        case CONNMAN_DEVICE_TYPE_CELLULAR:
-               network = __connman_element_get_network(element);
+               network = get_network(element);
                if (network == NULL)
                        return NULL;
                service = __connman_service_lookup_from_network(network);
@@ -233,32 +221,10 @@ struct connman_device *__connman_element_get_device(struct connman_element *elem
        return __connman_element_get_device(element->parent);
 }
 
-const char *__connman_element_get_device_path(struct connman_element *element)
-{
-       struct connman_device *device;
-
-       device = __connman_element_get_device(element);
-       if (device == NULL)
-               return NULL;
-
-       return connman_device_get_path(device);
-}
-
-const char *__connman_element_get_network_path(struct connman_element *element)
-{
-       if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
-                                               element->network != NULL)
-               return element->path;
-
-       if (element->parent == NULL)
-               return NULL;
-
-       return __connman_element_get_network_path(element->parent);
-}
-
 struct find_data {
        enum connman_service_type type;
        struct connman_device *device;
+       connman_bool_t error;
 };
 
 static gboolean find_device(GNode *node, gpointer user_data)
@@ -272,7 +238,7 @@ static gboolean find_device(GNode *node, gpointer user_data)
        if (element->device == NULL)
                return FALSE;
 
-       if (data->type != connman_device_get_type(element->device))
+       if (data->type != __connman_device_get_service_type(element->device))
                return FALSE;
 
        data->device = element->device;
@@ -312,6 +278,7 @@ static gboolean request_scan(GNode *node, gpointer user_data)
        case CONNMAN_SERVICE_TYPE_CELLULAR:
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_VPN:
+       case CONNMAN_SERVICE_TYPE_GADGET:
                return FALSE;
        case CONNMAN_SERVICE_TYPE_WIFI:
        case CONNMAN_SERVICE_TYPE_WIMAX:
@@ -341,6 +308,7 @@ static gboolean enable_technology(GNode *node, gpointer user_data)
        struct connman_element *element = node->data;
        struct find_data *data = user_data;
        enum connman_service_type type;
+       int err;
 
        if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
                return FALSE;
@@ -355,6 +323,7 @@ static gboolean enable_technology(GNode *node, gpointer user_data)
        case CONNMAN_SERVICE_TYPE_SYSTEM:
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_VPN:
+       case CONNMAN_SERVICE_TYPE_GADGET:
                return FALSE;
        case CONNMAN_SERVICE_TYPE_ETHERNET:
        case CONNMAN_SERVICE_TYPE_WIFI:
@@ -367,18 +336,23 @@ static gboolean enable_technology(GNode *node, gpointer user_data)
                break;
        }
 
-       __connman_device_enable_persistent(element->device);
+       err = __connman_device_enable_persistent(element->device);
+       if (err == 0 || (err < 0 && err == -EINPROGRESS))
+               data->error = FALSE;
 
        return FALSE;
 }
 
 int __connman_element_enable_technology(enum connman_service_type type)
 {
-       struct find_data data = { .type = type, .device = NULL };
+       struct find_data data = { .type = type, .device = NULL, .error = TRUE };
 
        g_node_traverse(element_root, G_PRE_ORDER,
                                G_TRAVERSE_ALL, -1, enable_technology, &data);
 
+       if (data.error == TRUE)
+               return -ENODEV;
+
        return 0;
 }
 
@@ -387,6 +361,7 @@ static gboolean disable_technology(GNode *node, gpointer user_data)
        struct connman_element *element = node->data;
        struct find_data *data = user_data;
        enum connman_service_type type;
+       int err;
 
        if (element->type != CONNMAN_ELEMENT_TYPE_DEVICE)
                return FALSE;
@@ -401,6 +376,7 @@ static gboolean disable_technology(GNode *node, gpointer user_data)
        case CONNMAN_SERVICE_TYPE_SYSTEM:
        case CONNMAN_SERVICE_TYPE_GPS:
        case CONNMAN_SERVICE_TYPE_VPN:
+       case CONNMAN_SERVICE_TYPE_GADGET:
                return FALSE;
        case CONNMAN_SERVICE_TYPE_ETHERNET:
        case CONNMAN_SERVICE_TYPE_WIFI:
@@ -413,18 +389,23 @@ static gboolean disable_technology(GNode *node, gpointer user_data)
                break;
        }
 
-       __connman_device_disable_persistent(element->device);
+       err = __connman_device_disable_persistent(element->device);
+       if (err == 0 || (err < 0 && err == -EINPROGRESS))
+               data->error = FALSE;
 
        return FALSE;
 }
 
 int __connman_element_disable_technology(enum connman_service_type type)
 {
-       struct find_data data = { .type = type, .device = NULL };
+       struct find_data data = { .type = type, .device = NULL, .error = TRUE };
 
        g_node_traverse(element_root, G_PRE_ORDER,
                                G_TRAVERSE_ALL, -1, disable_technology, &data);
 
+       if (data.error == TRUE)
+               return -ENODEV;
+
        return 0;
 }
 
@@ -603,6 +584,8 @@ struct connman_element *connman_element_create(const char *name)
 
        __connman_element_initialize(element);
 
+       element->name = g_strdup(name);
+
        return element;
 }
 
@@ -642,14 +625,10 @@ void connman_element_unref(struct connman_element *element)
                        element->destruct(element);
                free_children(element);
                free_properties(element);
-               g_free(element->ipv4.address);
-               g_free(element->ipv4.netmask);
-               g_free(element->ipv4.gateway);
-               g_free(element->ipv4.network);
-               g_free(element->ipv4.broadcast);
-               g_free(element->ipv4.nameserver);
-               g_free(element->ipv4.timeserver);
-               g_free(element->ipv4.pac);
+               g_free(element->hostname);
+               g_free(element->domainname);
+               g_free(element->ipv6.address);
+               g_free(element->ipv6.network);
                g_free(element->devname);
                g_free(element->path);
                g_free(element->name);
@@ -736,54 +715,25 @@ int connman_element_get_value(struct connman_element *element,
                return -EINVAL;
 
        switch (id) {
-       case CONNMAN_PROPERTY_ID_IPV4_METHOD:
-               if (element->ipv4.method == CONNMAN_IPCONFIG_METHOD_UNKNOWN)
+       case CONNMAN_PROPERTY_ID_HOSTNAME:
+               if (element->hostname == NULL)
                        return connman_element_get_value(element->parent,
                                                                id, value);
-               *((const char **) value) = __connman_ipconfig_method2string(element->ipv4.method);
+               *((char **) value) = element->hostname;
                break;
-       case CONNMAN_PROPERTY_ID_IPV4_ADDRESS:
-               if (element->ipv4.address == NULL)
+       case CONNMAN_PROPERTY_ID_DOMAINNAME:
+               if (element->domainname == NULL)
                        return connman_element_get_value(element->parent,
                                                                id, value);
-               *((char **) value) = element->ipv4.address;
+               *((char **) value) = element->domainname;
                break;
-       case CONNMAN_PROPERTY_ID_IPV4_NETMASK:
-               if (element->ipv4.netmask == NULL)
+       case CONNMAN_PROPERTY_ID_IPV6_GATEWAY:
+               if (element->ipv6.gateway == NULL)
                        return connman_element_get_value(element->parent,
                                                                id, value);
-               *((char **) value) = element->ipv4.netmask;
-               break;
-       case CONNMAN_PROPERTY_ID_IPV4_GATEWAY:
-               if (element->ipv4.gateway == NULL)
-                       return connman_element_get_value(element->parent,
-                                                               id, value);
-               *((char **) value) = element->ipv4.gateway;
-               break;
-       case CONNMAN_PROPERTY_ID_IPV4_BROADCAST:
-               if (element->ipv4.broadcast == NULL)
-                       return connman_element_get_value(element->parent,
-                                                               id, value);
-               *((char **) value) = element->ipv4.broadcast;
-               break;
-       case CONNMAN_PROPERTY_ID_IPV4_NAMESERVER:
-               if (element->ipv4.nameserver == NULL)
-                       return connman_element_get_value(element->parent,
-                                                               id, value);
-               *((char **) value) = element->ipv4.nameserver;
-               break;
-       case CONNMAN_PROPERTY_ID_IPV4_TIMESERVER:
-               if (element->ipv4.timeserver == NULL)
-                       return connman_element_get_value(element->parent,
-                                                               id, value);
-               *((char **) value) = element->ipv4.timeserver;
-               break;
-       case CONNMAN_PROPERTY_ID_IPV4_PAC:
-               if (element->ipv4.pac == NULL)
-                       return connman_element_get_value(element->parent,
-                                                               id, value);
-               *((char **) value) = element->ipv4.pac;
+               *((char **) value) = element->ipv6.gateway;
                break;
+
        default:
                return -EINVAL;
        }
@@ -1027,21 +977,27 @@ static void register_element(gpointer data, gpointer user_data)
 
 gboolean __connman_element_device_isfiltered(const char *devname)
 {
+       char **pattern;
+
        if (device_filter == NULL)
                goto nodevice;
 
-       if (g_pattern_match_simple(device_filter, devname) == FALSE) {
-               DBG("ignoring device %s (match)", devname);
-               return TRUE;
+       for (pattern = device_filter; *pattern; pattern++) {
+               if (g_pattern_match_simple(*pattern, devname) == FALSE) {
+                       DBG("ignoring device %s (match)", devname);
+                       return TRUE;
+               }
        }
 
 nodevice:
        if (nodevice_filter == NULL)
                return FALSE;
 
-       if (g_pattern_match_simple(nodevice_filter, devname) == TRUE) {
-               DBG("ignoring device %s (no match)", devname);
-               return TRUE;
+       for (pattern = nodevice_filter; *pattern; pattern++) {
+               if (g_pattern_match_simple(*pattern, devname) == TRUE) {
+                       DBG("ignoring device %s (no match)", devname);
+                       return TRUE;
+               }
        }
 
        return FALSE;
@@ -1082,9 +1038,6 @@ setup:
                }
        }
 
-       if (element->type == CONNMAN_ELEMENT_TYPE_DHCP)
-               element->ipv4.method = CONNMAN_IPCONFIG_METHOD_DHCP;
-
        element->parent = parent;
 
        register_element(element, NULL);
@@ -1102,8 +1055,7 @@ static gboolean remove_element(GNode *node, gpointer user_data)
        if (element == root)
                return FALSE;
 
-       if (node != NULL)
-               g_node_unlink(node);
+       g_node_unlink(node);
 
        if (element->driver) {
                if (element->driver->remove)
@@ -1112,14 +1064,50 @@ static gboolean remove_element(GNode *node, gpointer user_data)
                element->driver = NULL;
        }
 
-       if (node != NULL)
-               g_node_destroy(node);
+       g_node_destroy(node);
+
+       connman_element_unref(element);
+
+       return FALSE;
+}
+
+struct unregister_type {
+       struct connman_element *root;
+       enum connman_element_type type;
+};
+
+static gboolean remove_element_type(GNode *node, gpointer user_data)
+{
+       struct unregister_type *children_type = user_data;
+       struct connman_element *root = children_type->root;
+       struct connman_element *element = node->data;
+       enum connman_element_type type = children_type->type;
+
+       DBG("element %p name %s", element, element->name);
+
+       if (element == root)
+               return FALSE;
+
+       if(element->type != type)
+               return FALSE;
+
+       g_node_unlink(node);
+
+       if (element->driver) {
+               if (element->driver->remove)
+                       element->driver->remove(element);
+
+               element->driver = NULL;
+       }
+
+       g_node_destroy(node);
 
        connman_element_unref(element);
 
        return FALSE;
 }
 
+
 void connman_element_unregister(struct connman_element *element)
 {
        GNode *node;
@@ -1146,6 +1134,25 @@ void connman_element_unregister_children(struct connman_element *element)
                                G_TRAVERSE_ALL, -1, remove_element, element);
 }
 
+void connman_element_unregister_children_type(struct connman_element *element, enum connman_element_type type)
+{
+       GNode *node;
+
+       DBG("element %p name %s", element, element->name);
+
+       node = g_node_find(element_root, G_PRE_ORDER, G_TRAVERSE_ALL, element);
+
+       if (node != NULL) {
+               struct unregister_type children_type;
+
+               children_type.root = element;
+               children_type.type = type;
+               g_node_traverse(node, G_POST_ORDER,
+                               G_TRAVERSE_ALL, -1, remove_element_type, &children_type);
+       }
+}
+
+
 static gboolean update_element(GNode *node, gpointer user_data)
 {
        struct connman_element *element = node->data;
@@ -1226,6 +1233,28 @@ void connman_element_set_error(struct connman_element *element,
        __connman_service_indicate_error(service, convert_error(error));
 }
 
+void __connman_element_set_driver(struct connman_element *element)
+{
+       GSList *list;
+
+       DBG("element %p name %s driver %p", element, element->name,
+                                               element->driver);
+
+       if (element->driver)
+               return;
+
+       for (list = driver_list; list; list = list->next) {
+               struct connman_driver *driver = list->data;
+
+               if (match_driver(element, driver) == FALSE)
+                       continue;
+
+               element->driver = driver;
+
+               break;
+       }
+}
+
 int __connman_element_init(const char *device, const char *nodevice)
 {
        struct connman_element *element;
@@ -1236,8 +1265,11 @@ int __connman_element_init(const char *device, const char *nodevice)
        if (connection == NULL)
                return -EIO;
 
-       device_filter = g_strdup(device);
-       nodevice_filter = g_strdup(nodevice);
+       if (device)
+               device_filter = g_strsplit(device, ",", -1);
+
+       if (nodevice)
+               nodevice_filter = g_strsplit(nodevice, ",", -1);
 
        element = connman_element_create("root");
 
@@ -1286,14 +1318,12 @@ void __connman_element_start(void)
        started = TRUE;
 
        __connman_rtnl_start();
-       __connman_udev_start();
 
-       __connman_connection_init();
-       __connman_ipv4_init();
        __connman_dhcp_init();
+       __connman_wpad_init();
+       __connman_wispr_init();
 
-       if (__connman_rfkill_init() < 0)
-               __connman_udev_enable_rfkill_processing();
+       __connman_rfkill_init();
 }
 
 void __connman_element_stop(void)
@@ -1302,10 +1332,10 @@ void __connman_element_stop(void)
 
        __connman_rfkill_cleanup();
 
+       __connman_wispr_cleanup();
+       __connman_wpad_cleanup();
        __connman_dhcp_cleanup();
-       __connman_ipv4_cleanup();
        __connman_provider_cleanup();
-       __connman_connection_cleanup();
 }
 
 static gboolean free_driver(GNode *node, gpointer data)
@@ -1353,11 +1383,13 @@ void __connman_element_cleanup(void)
        g_node_traverse(element_root, G_POST_ORDER, G_TRAVERSE_ALL, -1,
                                                        free_node, NULL);
 
+       connman_element_unref(element_root->data);
+
        g_node_destroy(element_root);
        element_root = NULL;
 
-       g_free(nodevice_filter);
-       g_free(device_filter);
+       g_strfreev(nodevice_filter);
+       g_strfreev(device_filter);
 
        if (connection == NULL)
                return;