summaryrefslogtreecommitdiffstats
path: root/lib/yang.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/yang.c')
-rw-r--r--lib/yang.c57
1 files changed, 57 insertions, 0 deletions
diff --git a/lib/yang.c b/lib/yang.c
index f506d8bf2..06d29bb9c 100644
--- a/lib/yang.c
+++ b/lib/yang.c
@@ -774,6 +774,63 @@ LY_ERR yang_parse_notification(const char *xpath, LYD_FORMAT format,
return LY_SUCCESS;
}
+LY_ERR yang_parse_rpc(const char *xpath, LYD_FORMAT format, const char *data,
+ bool reply, struct lyd_node **rpc)
+{
+ const struct lysc_node *snode;
+ struct lyd_node *parent = NULL;
+ struct ly_in *in = NULL;
+ LY_ERR err;
+
+ snode = lys_find_path(ly_native_ctx, NULL, xpath, 0);
+ if (!snode) {
+ zlog_err("Failed to find RPC/action schema node: %s", xpath);
+ return LY_ENOTFOUND;
+ }
+
+ /* If it's an action, create its parent */
+ if (snode->nodetype == LYS_ACTION) {
+ char *parent_xpath = XSTRDUP(MTYPE_TMP, xpath);
+
+ if (yang_xpath_pop_node(parent_xpath) != NB_OK) {
+ XFREE(MTYPE_TMP, parent_xpath);
+ zlog_err("Invalid action xpath: %s", xpath);
+ return LY_EINVAL;
+ }
+
+ err = lyd_new_path2(NULL, ly_native_ctx, parent_xpath, NULL, 0,
+ 0, 0, NULL, &parent);
+ XFREE(MTYPE_TMP, parent_xpath);
+ if (err) {
+ zlog_err("Failed to create parent node for action: %s",
+ ly_last_errmsg());
+ return err;
+ }
+ } else if (snode->nodetype != LYS_RPC) {
+ zlog_err("Schema node is not an RPC/action: %s", xpath);
+ return LY_EINVAL;
+ }
+
+ err = ly_in_new_memory(data, &in);
+ if (err) {
+ lyd_free_all(parent);
+ zlog_err("Failed to initialize ly_in: %s", ly_last_errmsg());
+ return err;
+ }
+
+ err = lyd_parse_op(ly_native_ctx, parent, in, format,
+ reply ? LYD_TYPE_REPLY_YANG : LYD_TYPE_RPC_YANG,
+ NULL, rpc);
+ ly_in_free(in, 0);
+ if (err) {
+ lyd_free_all(parent);
+ zlog_err("Failed to parse RPC/action: %s", ly_last_errmsg());
+ return err;
+ }
+
+ return LY_SUCCESS;
+}
+
static ssize_t yang_print_darr(void *arg, const void *buf, size_t count)
{
uint8_t *dst = darr_append_n(*(uint8_t **)arg, count);