From e36d8124e142f27d99d16575b0122dc4401794cc Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 14 Sep 2009 06:01:38 -0700 Subject: Add support for monitoring operation state from plugins --- include/rtnl.h | 8 ++++++++ src/rtnl.c | 64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 71 insertions(+), 1 deletion(-) 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; }; @@ -50,6 +51,45 @@ struct watch_data { 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 @@ -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; -- cgit v1.2.3