diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f780790..0a46eab7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ ### Major New features ### API changes on existing features (you may need to change your code) +* Notification event streams enhancements + * Yang 1.1 notification support + * Event stream discovery support according to RFC 5277 Sec 3.2.5.1 (netconf) and RFC 8040 (restconf) * clixon_restconf and clixon_netconf now take -D as command-line option instead of just -D * This aligns to clixon_cli and clixon_backend * Application command option -S to clixon_netconf is obsolete. Use `clixon_netconf -l s` instead. diff --git a/apps/backend/backend_client.c b/apps/backend/backend_client.c index 224b371d..71714e68 100644 --- a/apps/backend/backend_client.c +++ b/apps/backend/backend_client.c @@ -99,20 +99,10 @@ client_subscription_add(struct client_entry *ce, return su; } -static struct client_entry * -ce_find_bypid(struct client_entry *ce_list, int pid) -{ - struct client_entry *ce; - - for (ce = ce_list; ce; ce = ce->ce_next) - if (ce->ce_pid == pid) - return ce; - return NULL; -} - +/*! Delete stream subscription from client subscription list */ static int client_subscription_delete(struct client_entry *ce, - struct client_subscription *su0) + struct client_subscription *su0) { struct client_subscription *su; struct client_subscription **su_prev; @@ -134,7 +124,8 @@ client_subscription_delete(struct client_entry *ce, #ifdef notused /* xxx */ static struct client_subscription * -client_subscription_find(struct client_entry *ce, char *stream) +client_subscription_find(struct client_entry *ce, + char *stream) { struct client_subscription *su = NULL; @@ -146,6 +137,18 @@ client_subscription_find(struct client_entry *ce, char *stream) } #endif +static struct client_entry * +ce_find_bypid(struct client_entry *ce_list, + int pid) +{ + struct client_entry *ce; + + for (ce = ce_list; ce; ce = ce->ce_next) + if (ce->ce_pid == pid) + return ce; + return NULL; +} + /*! Remove client entry state * Close down everything wrt clients (eg sockets, subscriptions) * Finally actually remove client struct in handle @@ -258,6 +261,79 @@ from_client_get_config(clicon_handle h, return retval; } +static int +client_get_streams(clicon_handle h, + char *xpath, + cxobj **xtop) +{ + int retval = -1; + cxobj *x = NULL; + cxobj *xc; + char *reason = NULL; + yang_spec *yspec; + cbuf *cb; + + if ((yspec = clicon_dbspec_yang(h)) == NULL){ + clicon_err(OE_YANG, ENOENT, "No yang spec"); + goto done; + } + if (*xtop==NULL){ + clicon_err(OE_CFG, ENOENT, "XML tree expected"); + goto done; + } + if ((cb = cbuf_new()) == NULL){ + clicon_err(OE_UNIX, 0, "clicon buffer"); + goto done; + } + cprintf(cb,""); + if (stream_get_xml(h, cb) < 0) + goto done; + cprintf(cb,""); + /* XXX. yspec */ + if (xml_parse_string(cbuf_get(cb), NULL, &x) < 0) + goto done; + if (xml_merge(*xtop, x, yspec, &reason) < 0) + goto done; + if (reason){ + while ((xc = xml_child_i(*xtop, 0)) != NULL) + xml_purge(xc); + if (netconf_operation_failed_xml(xtop, "rpc", reason)< 0) + goto done; + goto ok; + } +#ifdef notyet + /* Code complex to filter out anything that is outside of xpath */ + if (xpath_vec(*xtop, "%s", &xvec, &xlen, xpath?xpath:"/") < 0) + goto done; + + /* If vectors are specified then mark the nodes found and + * then filter out everything else, + * otherwise return complete tree. + */ + if (xvec != NULL){ + for (i=0; i