summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-09-14 06:01:38 -0700
committerMarcel Holtmann <marcel@holtmann.org>2009-09-14 06:01:38 -0700
commite36d8124e142f27d99d16575b0122dc4401794cc (patch)
treec066e8899733104b97e4f08c693ff0c369c194f9
parent8e8f874898bf2f7d05440069b5b906bb46dfbb4f (diff)
downloadconnman-e36d8124e142f27d99d16575b0122dc4401794cc.tar.gz
connman-e36d8124e142f27d99d16575b0122dc4401794cc.tar.bz2
connman-e36d8124e142f27d99d16575b0122dc4401794cc.zip
Add support for monitoring operation state from plugins
-rw-r--r--include/rtnl.h8
-rw-r--r--src/rtnl.c64
2 files changed, 71 insertions, 1 deletions
diff --git a/include/rtnl.h b/include/rtnl.h
index 01f4d2f8..1c3bd048 100644
--- a/include/rtnl.h
+++ b/include/rtnl.h
@@ -32,11 +32,19 @@ extern "C" {
* @short_description: Functions for registering RTNL modules
*/
+
+typedef void (* connman_rtnl_operstate_cb_t) (unsigned char operstate,
+ void *user_data);
+
typedef void (* connman_rtnl_link_cb_t) (unsigned flags, unsigned change,
void *user_data);
+unsigned int connman_rtnl_add_operstate_watch(int index,
+ connman_rtnl_operstate_cb_t callback, void *user_data);
+
unsigned int connman_rtnl_add_newlink_watch(int index,
connman_rtnl_link_cb_t callback, void *user_data);
+
void connman_rtnl_remove_watch(unsigned int id);
#define CONNMAN_RTNL_PRIORITY_LOW -100
diff --git a/src/rtnl.c b/src/rtnl.c
index 332d67ae..6d2efa24 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -43,6 +43,7 @@
struct watch_data {
unsigned int id;
int index;
+ connman_rtnl_operstate_cb_t operstate;
connman_rtnl_link_cb_t newlink;
void *user_data;
};
@@ -51,6 +52,45 @@ static GSList *watch_list = NULL;
static unsigned int watch_id = 0;
/**
+ * connman_rtnl_add_operstate_watch:
+ * @index: network device index
+ * @callback: callback function
+ * @user_data: callback data;
+ *
+ * Add a new RTNL watch for operation state events
+ *
+ * Returns: %0 on failure and a unique id on success
+ */
+unsigned int connman_rtnl_add_operstate_watch(int index,
+ connman_rtnl_operstate_cb_t callback, void *user_data)
+{
+ struct watch_data *watch;
+
+ watch = g_try_new0(struct watch_data, 1);
+ if (watch == NULL)
+ return 0;
+
+ watch->id = ++watch_id;
+ watch->index = index;
+
+ watch->operstate = callback;
+ watch->user_data = user_data;
+
+ watch_list = g_slist_prepend(watch_list, watch);
+
+ DBG("id %d", watch->id);
+
+ if (callback) {
+ unsigned char operstate = 0;
+
+ if (operstate > 0)
+ callback(operstate, user_data);
+ }
+
+ return watch->id;
+}
+
+/**
* connman_rtnl_add_newlink_watch:
* @index: network device index
* @callback: callback function
@@ -239,7 +279,7 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
extract_link(msg, bytes, &ifname, &operstate);
if (operstate != 0xff)
- connman_info("%s {state} index %d operstate %d <%s>",
+ connman_info("%s {newlink} index %d operstate %d <%s>",
ifname, index, operstate,
operstate2str(operstate));
@@ -256,6 +296,9 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
if (watch->index != index)
continue;
+ if (operstate != 0xff && watch->operstate)
+ watch->operstate(operstate, watch->user_data);
+
if (watch->newlink)
watch->newlink(flags, change, watch->user_data);
}
@@ -264,8 +307,27 @@ static void process_newlink(unsigned short type, int index, unsigned flags,
static void process_dellink(unsigned short type, int index, unsigned flags,
unsigned change, struct ifinfomsg *msg, int bytes)
{
+ unsigned char operstate = 0xff;
+ const char *ifname = NULL;
GSList *list;
+ extract_link(msg, bytes, &ifname, &operstate);
+
+ if (operstate != 0xff)
+ connman_info("%s {dellink} index %d operstate %d <%s>",
+ ifname, index, operstate,
+ operstate2str(operstate));
+
+ for (list = watch_list; list; list = list->next) {
+ struct watch_data *watch = list->data;
+
+ if (watch->index != index)
+ continue;
+
+ if (operstate != 0xff && watch->operstate)
+ watch->operstate(operstate, watch->user_data);
+ }
+
for (list = rtnl_list; list; list = list->next) {
struct connman_rtnl *rtnl = list->data;