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;
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;
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)
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)
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);
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);
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)
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;
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:
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;
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:
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;
}
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;
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:
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;
}
__connman_element_initialize(element);
+ element->name = g_strdup(name);
+
return 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);
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;
}
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;
}
}
- if (element->type == CONNMAN_ELEMENT_TYPE_DHCP)
- element->ipv4.method = CONNMAN_IPCONFIG_METHOD_DHCP;
-
element->parent = parent;
register_element(element, NULL);
if (element == root)
return FALSE;
- if (node != NULL)
- g_node_unlink(node);
+ g_node_unlink(node);
if (element->driver) {
if (element->driver->remove)
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;
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;
__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;
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");
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)
__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)
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;