summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2010-07-15 09:51:29 -0700
committerMarcel Holtmann <marcel@holtmann.org>2010-07-15 09:51:29 -0700
commitcd145e6119b67833c68e618dd668a02f828fbadf (patch)
tree46eed8fab6f1007cd8c0f9b63b5a6c546ff58fd8
parentd2fb4f63ca444073956b3736420e6d05b409e784 (diff)
downloadconnman-cd145e6119b67833c68e618dd668a02f828fbadf.tar.gz
connman-cd145e6119b67833c68e618dd668a02f828fbadf.tar.bz2
connman-cd145e6119b67833c68e618dd668a02f828fbadf.zip
Monitor interface creation/removal and check DEVTYPE
-rw-r--r--src/rtnl.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/src/rtnl.c b/src/rtnl.c
index 2e0fca98..74eafc69 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -56,6 +56,61 @@ static GSList *update_list = NULL;
static guint update_interval = G_MAXUINT;
static guint update_timeout = 0;
+struct interface_data {
+ int index;
+ char *name;
+ enum connman_service_type type;
+};
+
+static GHashTable *interface_list = NULL;
+
+static void free_interface(gpointer data)
+{
+ struct interface_data *interface = data;
+
+ connman_info("Remove interface %s [ %s ]", interface->name,
+ __connman_service_type2string(interface->type));
+
+ g_free(interface->name);
+ g_free(interface);
+}
+
+static void read_uevent(struct interface_data *interface)
+{
+ char *filename, line[128];
+ FILE *f;
+
+ filename = g_strdup_printf("/sys/class/net/%s/uevent",
+ interface->name);
+
+ f = fopen(filename, "re");
+ if (f == NULL)
+ return;
+
+ while (fgets(line, sizeof(line), f)) {
+ char *pos;
+
+ pos = strchr(line, '\n');
+ if (pos == NULL)
+ continue;
+ pos[0] = '\0';
+
+ if (strncmp(line, "DEVTYPE=", 8) != 0)
+ continue;
+
+ if (strcmp(line + 8, "wlan") == 0)
+ interface->type = CONNMAN_SERVICE_TYPE_WIFI;
+ else if (strcmp(line + 8, "wwan") == 0)
+ interface->type = CONNMAN_SERVICE_TYPE_CELLULAR;
+ else if (strcmp(line + 8, "bluetooth") == 0)
+ interface->type = CONNMAN_SERVICE_TYPE_BLUETOOTH;
+ else if (strcmp(line + 8, "wimax") == 0)
+ interface->type = CONNMAN_SERVICE_TYPE_WIMAX;
+ }
+
+ fclose(f);
+}
+
/**
* connman_rtnl_add_operstate_watch:
* @index: network device index
@@ -322,6 +377,21 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
ifname, index, operstate,
operstate2str(operstate));
+ if (g_hash_table_lookup(interface_list, &index) == NULL) {
+ struct interface_data *interface;
+
+ interface = g_new0(struct interface_data, 1);
+ interface->index = index;
+ interface->name = g_strdup(ifname);
+
+ g_hash_table_insert(interface_list, &index, interface);
+
+ read_uevent(interface);
+
+ connman_info("Create interface %s [ %s ]", interface->name,
+ __connman_service_type2string(interface->type));
+ }
+
for (list = rtnl_list; list; list = list->next) {
struct connman_rtnl *rtnl = list->data;
@@ -383,6 +453,8 @@ static void process_dellink(unsigned short type, int index, unsigned flags,
__connman_ipconfig_dellink(index, &stats);
break;
}
+
+ g_hash_table_remove(interface_list, &index);
}
static void extract_addr(struct ifaddrmsg *msg, int bytes,
@@ -1156,6 +1228,9 @@ int __connman_rtnl_init(void)
DBG("");
+ interface_list = g_hash_table_new_full(g_int_hash, g_int_equal,
+ NULL, free_interface);
+
sk = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
if (sk < 0)
return -1;
@@ -1227,4 +1302,6 @@ void __connman_rtnl_cleanup(void)
g_io_channel_unref(channel);
channel = NULL;
+
+ g_hash_table_destroy(interface_list);
}