diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2009-09-14 06:01:38 -0700 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-09-14 06:01:38 -0700 |
commit | e36d8124e142f27d99d16575b0122dc4401794cc (patch) | |
tree | c066e8899733104b97e4f08c693ff0c369c194f9 | |
parent | 8e8f874898bf2f7d05440069b5b906bb46dfbb4f (diff) | |
download | connman-e36d8124e142f27d99d16575b0122dc4401794cc.tar.gz connman-e36d8124e142f27d99d16575b0122dc4401794cc.tar.bz2 connman-e36d8124e142f27d99d16575b0122dc4401794cc.zip |
Add support for monitoring operation state from plugins
-rw-r--r-- | include/rtnl.h | 8 | ||||
-rw-r--r-- | src/rtnl.c | 64 |
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 @@ -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; |