CHANGE libnetconf -> libnetconf2

Also some bugfixes.
diff --git a/src/netopeerguid.c b/src/netopeerguid.c
index 88f6e3d..e31fa98 100644
--- a/src/netopeerguid.c
+++ b/src/netopeerguid.c
@@ -63,8 +63,7 @@
 #include <pthread.h>
 #include <ctype.h>
 
-#include <libnetconf.h>
-#include <libnetconf_ssh.h>
+#include <nc_client.h>
 
 #include "../config.h"
 
@@ -119,7 +118,7 @@
 json_object *create_data_reply(const char *data);
 static char *netconf_getschema(unsigned int session_key, const char *identifier, const char *version,
                                const char *format, json_object **err);
-static void node_add_metadata_recursive(struct lyd_node *data_tree, struct lys_module *module,
+static void node_add_metadata_recursive(struct lyd_node *data_tree, const struct lys_module *module,
                                         json_object *data_json_parent);
 static void node_metadata_typedef(struct lys_tpdf *tpdf, json_object *parent);
 
@@ -142,7 +141,7 @@
 }
 
 char *
-netconf_callback_sshauth_passphrase(const char *UNUSED(username), const char *UNUSED(hostname), const char *UNUSED(priv_key_file))
+netconf_callback_sshauth_passphrase(const char *UNUSED(priv_key_file))
 {
     char *buf;
     buf = strdup(password);
@@ -218,12 +217,14 @@
 void
 prepare_status_message(struct session_with_mutex *s, struct nc_session *session)
 {
+    int i;
     json_object *json_obj = NULL;
     json_object *js_tmp = NULL;
     char *old_sid = NULL;
     const char *j_old_sid = NULL;
-    const char *cpbltstr;
-    struct nc_cpblts* cpblts = NULL;
+    char str_port[6];
+    const char **cpblts;
+    struct lyd_node *yanglib, *module, *node;
 
     if (s == NULL) {
         ERROR("No session given.");
@@ -244,28 +245,46 @@
     }
     s->hello_message = json_object_new_object();
     if (session != NULL) {
-        if (old_sid != NULL) {
-            /* use previous sid */
-            json_object_object_add(s->hello_message, "sid", json_object_new_string(old_sid));
-            free(old_sid);
-            old_sid = NULL;
-        } else {
+        if (!old_sid) {
             /* we don't have old sid */
-            json_object_object_add(s->hello_message, "sid", json_object_new_string(nc_session_get_id(session)));
+            asprintf(&old_sid, "%u", nc_session_get_id(session));
         }
-        json_object_object_add(s->hello_message, "version", json_object_new_string((nc_session_get_version(session) == 0)?"1.0":"1.1"));
+        json_object_object_add(s->hello_message, "sid", json_object_new_string(old_sid));
+        free(old_sid);
+        old_sid = NULL;
+
+        json_object_object_add(s->hello_message, "version", json_object_new_string((nc_session_get_version(session) ? "1.1":"1.0")));
         json_object_object_add(s->hello_message, "host", json_object_new_string(nc_session_get_host(session)));
-        json_object_object_add(s->hello_message, "port", json_object_new_string(nc_session_get_port(session)));
-        json_object_object_add(s->hello_message, "user", json_object_new_string(nc_session_get_user(session)));
-        cpblts = nc_session_get_cpblts (session);
-        if (cpblts != NULL) {
+        sprintf(str_port, "%u", nc_session_get_port(session));
+        json_object_object_add(s->hello_message, "port", json_object_new_string(str_port));
+        json_object_object_add(s->hello_message, "user", json_object_new_string(nc_session_get_username(session)));
+        cpblts = nc_session_get_cpblts(session);
+        if (cpblts) {
             json_obj = json_object_new_array();
-            nc_cpblts_iter_start (cpblts);
-            while ((cpbltstr = nc_cpblts_iter_next (cpblts)) != NULL) {
-                json_object_array_add(json_obj, json_object_new_string(cpbltstr));
+            for (i = 0; cpblts[i]; ++i) {
+                json_object_array_add(json_obj, json_object_new_string(cpblts[i]));
             }
             json_object_object_add(s->hello_message, "capabilities", json_obj);
         }
+
+        yanglib = ly_ctx_info(nc_session_get_ctx(session));
+        if (yanglib) {
+            json_obj = json_object_new_array();
+            LY_TREE_FOR(yanglib->child, module) {
+                if (!strcmp(module->schema->name, "module")) {
+                    LY_TREE_FOR(module->child, node) {
+                        if (!strcmp(node->schema->name, "name")) {
+                            json_object_array_add(json_obj, json_object_new_string(((struct lyd_node_leaf_list *)node)->value_str));
+                            break;
+                        }
+                    }
+                }
+            }
+            json_object_object_add(s->hello_message, "models", json_obj);
+
+            lyd_free(node);
+        }
+
         DEBUG("%s", json_object_to_json_string(s->hello_message));
     } else {
         ERROR("Session was not given.");
@@ -274,7 +293,6 @@
     }
     DEBUG("Status info from hello message prepared");
     pthread_mutex_unlock(&json_lock);
-
 }
 
 void
@@ -370,7 +388,7 @@
     struct session_with_mutex *sess;
 
     for (sess = netconf_sessions_list; sess; sess = sess->next) {
-        if (!strcmp(nc_session_get_user(sess->session), username)) {
+        if (!strcmp(nc_session_get_username(sess->session), username)) {
             sess->last_activity = time(NULL);
         }
     }
@@ -997,7 +1015,7 @@
 }
 
 static void
-node_metadata_model(struct lys_module *module, json_object *parent)
+node_metadata_model(const struct lys_module *module, json_object *parent)
 {
     json_object *obj, *array, *item;
     int i;
@@ -1077,279 +1095,31 @@
  * \param[in] rpc     prepared RPC message
  * \param[in] timeout timeout in miliseconds, -1 for blocking, 0 for non-blocking
  * \param[out] reply  reply from the server
- * \return Value from nc_session_recv_reply() or NC_MSG_UNKNOWN when send_rpc() fails.
+ * \return NC_MSG_WOULDBLOCK or NC_MSG_ERROR.
  * On success, it returns NC_MSG_REPLY.
  */
 NC_MSG_TYPE
-netconf_send_recv_timed(struct nc_session *session, nc_rpc *rpc, int timeout, nc_reply **reply)
+netconf_send_recv_timed(struct nc_session *session, struct nc_rpc *rpc, int timeout, int strict, struct nc_reply **reply)
 {
-    const nc_msgid msgid = NULL;
-    NC_MSG_TYPE ret = NC_MSG_UNKNOWN;
-    msgid = nc_session_send_rpc(session, rpc);
-    if (msgid == NULL) {
+    uint64_t msgid;
+    NC_MSG_TYPE ret;
+    ret = nc_send_rpc(session, rpc, timeout, &msgid);
+    if (ret != NC_MSG_RPC) {
         return ret;
     }
-    do {
-        ret = nc_session_recv_reply(session, timeout, reply);
-        if (ret == NC_MSG_HELLO) {
-            ERROR("<hello> received instead reply, it will be lost.");
-            nc_reply_free(*reply);
-        }
-        if (ret == NC_MSG_WOULDBLOCK) {
-            ERROR("Timeout for receiving RPC reply expired.");
-            break;
-        }
-    } while (ret == NC_MSG_HELLO || ret == NC_MSG_NOTIFICATION);
+
+    while ((ret = nc_recv_reply(session, rpc, msgid, timeout, (strict ? LYD_OPT_STRICT : 0), reply)) == NC_MSG_NOTIF);
+
     return ret;
 }
 
-static int
-ctx_download_module(struct session_with_mutex *session, const char *model_name, const char *revision, const char *schema_dir)
-{
-    json_object *err = NULL;
-    char *model_data = NULL, *model_path;
-    size_t length;
-    FILE *file;
-
-    DEBUG("UNLOCK rwlock %s", __func__);
-    if (pthread_rwlock_unlock(&session_lock) != 0) {
-        ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
-        return 1;
-    }
-
-    model_data = netconf_getschema(session->session_key, model_name, revision, "yin", &err);
-
-    DEBUG("LOCK rwlock %s", __func__);
-    if (pthread_rwlock_wrlock(&session_lock) != 0) {
-        ERROR("Error while locking rwlock: %d (%s)", errno, strerror(errno));
-        return 1;
-    }
-
-    if (!model_data) {
-        if (err) {
-            json_object_put(err);
-        }
-        ERROR("Failed to get-schema of \"%s\".", model_name);
-        return 1;
-    }
-
-    if (revision) {
-        asprintf(&model_path, "%s/%s@%s.yin", schema_dir, model_name, revision);
-    } else {
-        asprintf(&model_path, "%s/%s.yin", schema_dir, model_name);
-    }
-
-    file = fopen(model_path, "w");
-    if (!file) {
-        ERROR("Failed to open \"%s\" for writing (%s).", model_path, strerror(errno));
-        free(model_data);
-        free(model_path);
-        return 1;
-    }
-    free(model_path);
-
-    length = strlen(model_data);
-    if (fwrite(model_data, 1, length, file) < length) {
-        ERROR("Failed to store the model \"%s\".", model_name);
-        free(model_data);
-        fclose(file);
-        return 1;
-    }
-
-    free(model_data);
-    fclose(file);
-    return 0;
-}
-
-static void
-ctx_enable_features(struct lys_module *module, const char *cpblt)
-{
-    char *ptr, *ptr2, *features = NULL;
-
-    /* parse features */
-    ptr = strstr(cpblt, "features=");
-    if (ptr) {
-        ptr += 9;
-        ptr2 = strchr(ptr, '&');
-        if (!ptr2) {
-            ptr2 = ptr + strlen(ptr);
-        }
-        features = strndup(ptr, ptr2 - ptr);
-    }
-
-    /* enable features */
-    if (features) {
-        /* basically manual strtok_r (to avoid macro) */
-        ptr2 = features;
-        for (ptr = features; *ptr; ++ptr) {
-            if (*ptr == ',') {
-                *ptr = '\0';
-                /* remember last feature */
-                ptr2 = ptr + 1;
-            }
-        }
-
-        ptr = features;
-        lys_features_enable(module, ptr);
-        while (ptr != ptr2) {
-            ptr += strlen(ptr) + 1;
-            lys_features_enable(module, ptr);
-        }
-
-        free(features);
-    }
-}
-
-static void
-ctx_enable_capabs(struct lys_module *ietfnc, json_object *cpb_array)
-{
-    json_object *item;
-    int i;
-    const char *capab;
-
-    /* set supported capabilities from ietf-netconf */
-    for (i = 0; i < json_object_array_length(cpb_array); ++i) {
-        item = json_object_array_get_idx(cpb_array, i);
-        capab = json_object_get_string(item);
-
-        if (!strncmp(capab, "urn:ietf:params:netconf:capability:", 35)) {
-            if (!strncmp(capab, "writable-running", 16)) {
-                lys_features_enable(ietfnc, "writable-running");
-            } else if (!strncmp(capab, "candidate", 9)) {
-                lys_features_enable(ietfnc, "candidate");
-            } else if (!strcmp(capab, "confirmed-commit:1.1")) {
-                lys_features_enable(ietfnc, "confirmed-commit");
-            } else if (!strncmp(capab, "rollback-on-error", 17)) {
-                lys_features_enable(ietfnc, "rollback-on-error");
-            } else if (!strcmp(capab, "validate:1.1")) {
-                lys_features_enable(ietfnc, "validate");
-            } else if (!strncmp(capab, "startup", 7)) {
-                lys_features_enable(ietfnc, "startup");
-            } else if (!strncmp(capab, "url", 3)) {
-                lys_features_enable(ietfnc, "url");
-            } else if (!strncmp(capab, "xpath", 5)) {
-                lys_features_enable(ietfnc, "xpath");
-            }
-        }
-    }
-}
-
-static int
-prepare_context(struct session_with_mutex *session)
-{
-    struct lys_module *module;
-    json_object *array, *item;
-    char *ptr, *ptr2;
-    char *model_name = NULL, *revision = NULL;
-    const char *capab;
-    int i, get_schema_support;
-
-    if (json_object_object_get_ex(session->hello_message, "capabilities", &array) == FALSE) {
-        return 1;
-    }
-
-    get_schema_support = 0;
-    for (i = 0; i < json_object_array_length(array); ++i) {
-        item = json_object_array_get_idx(array, i);
-        capab = json_object_get_string(item);
-
-        if (!strncmp(capab, "urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring", 51)) {
-            get_schema_support = 1;
-            break;
-        }
-    }
-
-    if (get_schema_support) {
-        errno = 0;
-        if (eaccess(SCHEMA_DIR, W_OK)) {
-            if (errno == ENOENT) {
-                if (mkdir(SCHEMA_DIR, 00755)) {
-                    ERROR("Failed to create temp model dir \"%s\" (%s).", SCHEMA_DIR, strerror(errno));
-                    return 1;
-                }
-            } else {
-                ERROR("Unable to write to temp model dir \"%s\" (%s).", SCHEMA_DIR, strerror(errno));
-                return 1;
-            }
-        }
-
-        session->ctx = ly_ctx_new(SCHEMA_DIR);
-    } else {
-        /* TODO try to load models from a local directory */
-        session->ctx = ly_ctx_new(NULL);
-    }
-
-loop:
-    /* download all the models first or load them directly */
-    for (i = 0; i < json_object_array_length(array); ++i) {
-        item = json_object_array_get_idx(array, i);
-        capab = json_object_get_string(item);
-        if (!strncmp(capab, "urn:ietf:params:netconf:capability", 34)
-                || !strncmp(capab, "urn:ietf:params:netconf:base", 28)) {
-            continue;
-        }
-
-        /* get module */
-        ptr = strstr(capab, "module=");
-        if (!ptr) {
-        ERROR("Unknown capability \"%s\" could not be parsed.", capab);
-            continue;
-        }
-        ptr += 7;
-        ptr2 = strchr(ptr, '&');
-        if (!ptr2) {
-            ptr2 = ptr + strlen(ptr);
-        }
-        model_name = strndup(ptr, ptr2 - ptr);
-
-        /* get revision */
-        ptr = strstr(capab, "revision=");
-        if (ptr) {
-            ptr += 9;
-            ptr2 = strchr(ptr, '&');
-            if (!ptr2) {
-                ptr2 = ptr + strlen(ptr);
-            }
-            revision = strndup(ptr, ptr2 - ptr);
-        }
-
-        if (get_schema_support) {
-            ctx_download_module(session, model_name, revision, SCHEMA_DIR);
-        } else {
-            module = ly_ctx_get_module(session->ctx, model_name, revision);
-            if (!module) {
-                module = ly_ctx_load_module(session->ctx, model_name, revision);
-                if (module) {
-                    if (!strcmp(module->name, "ietf-netconf")) {
-                        ctx_enable_capabs(module, array);
-                    } else {
-                        ctx_enable_features(module, capab);
-                    }
-                }
-            }
-        }
-
-        free(model_name);
-        free(revision);
-        revision = NULL;
-    }
-
-    if (get_schema_support) {
-        /* we have downloaded all the models, load them now */
-        get_schema_support = 0;
-        goto loop;
-    }
-
-    return 0;
-}
-
 /**
  * \brief Connect to NETCONF server
  *
  * \warning Session_key hash is not bound with caller identification. This could be potential security risk.
  */
 static unsigned int
-netconf_connect(const char *host, const char *port, const char *user, const char *pass, const char *privkey, struct nc_cpblts *cpblts)
+netconf_connect(const char *host, const char *port, const char *user, const char *pass, const char *privkey)
 {
     struct nc_session* session = NULL;
     struct session_with_mutex *locked_session, *last_session;
@@ -1358,13 +1128,14 @@
     /* connect to the requested NETCONF server */
     password = (char*)pass;
     if (privkey) {
-        nc_ssh_pref(NC_SSH_AUTH_PUBLIC_KEYS, 3);
+        nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, 3);
         asprintf(&pubkey, "%s.pub", privkey);
-        nc_set_keypair_path(privkey, pubkey);
+        nc_client_ssh_add_keypair(pubkey, privkey);
         free(pubkey);
     }
+    nc_client_ssh_set_username(user);
     DEBUG("prepare to connect %s@%s:%s", user, host, port);
-    session = nc_session_connect(host, (unsigned short) atoi (port), user, cpblts);
+    session = nc_connect_ssh(host, (unsigned short)atoi(port), NULL);
     DEBUG("nc_session_connect done");
 
     /* if connected successful, add session to the list */
@@ -1399,23 +1170,13 @@
             last_session->next = locked_session;
             locked_session->prev = last_session;
         }
-        session_user_activity(nc_session_get_user(locked_session->session));
+        session_user_activity(nc_session_get_username(locked_session->session));
 
         /* no need to lock session, noone can read it while we have wrlock */
 
         /* store information about session from hello message for future usage */
         prepare_status_message(locked_session, session);
 
-        /* create context from the hello message cpabilities */
-        if (prepare_context(locked_session)) {
-            nc_session_free(session);
-            free(locked_session);
-            DEBUG("UNLOCK wrlock %s", __func__);
-            pthread_rwlock_unlock(&session_lock);
-            ERROR("Failed to prepare context");
-            return 0;
-        }
-
         DEBUG("NETCONF session established");
         locked_session->session_key = session_key_generator;
         ++session_key_generator;
@@ -1475,7 +1236,6 @@
         locked_session->hello_message = NULL;
     }
     locked_session->session = NULL;
-    ly_ctx_destroy(locked_session->ctx);
     free(locked_session);
     locked_session = NULL;
     DEBUG("NETCONF session closed, everything cleared.");
@@ -1544,15 +1304,14 @@
  * \return NULL on success
  */
 json_object *
-netconf_test_reply(struct nc_session *session, unsigned int session_key, NC_MSG_TYPE msgt, nc_reply *reply, char **data)
+netconf_test_reply(struct nc_session *session, unsigned int session_key, NC_MSG_TYPE msgt, struct nc_reply *reply, struct lyd_node **data)
 {
-    NC_REPLY_TYPE replyt;
     json_object *err = NULL;
 
     /* process the result of the operation */
     switch (msgt) {
-        case NC_MSG_UNKNOWN:
-            if (nc_session_get_status(session) != NC_SESSION_STATUS_WORKING) {
+        case NC_MSG_ERROR:
+            if (nc_session_get_status(session) != NC_STATUS_RUNNING) {
                 ERROR("mod_netconf: receiving rpc-reply failed");
                 if (session_key) {
                     netconf_close(session_key, &err);
@@ -1570,30 +1329,31 @@
             }
             return NULL;
         case NC_MSG_REPLY:
-            switch (replyt = nc_reply_get_type(reply)) {
-                case NC_REPLY_OK:
+            switch (reply->type) {
+                case NC_RPL_OK:
                     if ((data != NULL) && (*data != NULL)) {
                         free(*data);
                         (*data) = NULL;
                     }
                     return create_ok_reply();
-                case NC_REPLY_DATA:
-                    if (((*data) = nc_reply_get_data(reply)) == NULL) {
+                case NC_RPL_DATA:
+                    if (((*data) = ((struct nc_reply_data *)reply)->data) == NULL) {
                         ERROR("mod_netconf: no data from reply");
                         return create_error_reply("Internal: No data from reply received.");
                     } else {
+                        ((struct nc_reply_data *)reply)->data = NULL;
                         return NULL;
                     }
                     break;
-                case NC_REPLY_ERROR:
-                    ERROR("mod_netconf: unexpected rpc-reply (%d)", replyt);
+                case NC_RPL_ERROR:
+                    ERROR("mod_netconf: unexpected rpc-reply (%d)", reply->type);
                     if (data != NULL) {
                         free(*data);
                         (*data) = NULL;
                     }
-                    return create_error_reply(nc_reply_get_errormsg(reply));
+                    return create_error_reply(((struct nc_reply_error *)reply)->err[0].message);
                 default:
-                    ERROR("mod_netconf: unexpected rpc-reply (%d)", replyt);
+                    ERROR("mod_netconf: unexpected rpc-reply (%d)", reply->type);
                     if (data != NULL) {
                         free(*data);
                         (*data) = NULL;
@@ -1612,9 +1372,9 @@
 }
 
 json_object *
-netconf_unlocked_op(struct nc_session *session, nc_rpc *rpc)
+netconf_unlocked_op(struct nc_session *session, struct nc_rpc *rpc)
 {
-    nc_reply* reply = NULL;
+    struct nc_reply* reply = NULL;
     NC_MSG_TYPE msgt;
 
     /* check requests */
@@ -1625,7 +1385,7 @@
 
     if (session != NULL) {
         /* send the request and get the reply */
-        msgt = netconf_send_recv_timed(session, rpc, 50000, &reply);
+        msgt = netconf_send_recv_timed(session, rpc, 50000, 0, &reply);
         /* process the result of the operation */
         return netconf_test_reply(session, 0, msgt, reply, NULL);
     } else {
@@ -1643,12 +1403,12 @@
  * \return NULL on success, json object with error otherwise
  */
 static json_object *
-netconf_op(unsigned int session_key, nc_rpc *rpc, char **received_data)
+netconf_op(unsigned int session_key, struct nc_rpc *rpc, int strict, struct lyd_node **received_data)
 {
     struct session_with_mutex * locked_session;
-    nc_reply* reply = NULL;
+    struct nc_reply* reply = NULL;
     json_object *res = NULL;
-    char *data = NULL;
+    struct lyd_node *data = NULL;
     NC_MSG_TYPE msgt;
 
     /* check requests */
@@ -1665,10 +1425,10 @@
         goto finished;
     }
 
-    session_user_activity(nc_session_get_user(locked_session->session));
+    session_user_activity(nc_session_get_username(locked_session->session));
 
     /* send the request and get the reply */
-    msgt = netconf_send_recv_timed(locked_session->session, rpc, 2000000, &reply);
+    msgt = netconf_send_recv_timed(locked_session->session, rpc, 2000000, strict, &reply);
 
     session_unlock(locked_session);
 
@@ -1690,39 +1450,25 @@
 static char *
 netconf_getconfig(unsigned int session_key, NC_DATASTORE source, const char *filter, int strict, json_object **err)
 {
-    nc_rpc* rpc;
-    struct nc_filter *f = NULL;
+    struct nc_rpc* rpc;
     struct session_with_mutex *locked_session;
-    char* data = NULL, *data_xml;
     json_object *res = NULL, *data_cjson;
     enum json_tokener_error tok_err;
-    struct lyd_node *node, *sibling, *next;
+    char *data_json;
+    struct lyd_node *data, *sibling, *next;
 
-    /* create filter if set */
-    if (filter != NULL) {
-        f = nc_filter_new(NC_FILTER_SUBTREE, filter);
-    }
-
-    /* create requests */
-    rpc = nc_rpc_getconfig(source, f);
-    nc_filter_free(f);
+    /* tell server to show all elements even if they have default values */
+#ifdef HAVE_WITHDEFAULTS_TAGGED
+    rpc = nc_rpc_getconfig(source, filter, NC_WD_MODE_ALL_TAG, NC_PARAMTYPE_CONST);
+#else
+    rpc = nc_rpc_getconfig(source, filter, 0, NC_PARAMTYPE_CONST);
+#endif
     if (rpc == NULL) {
         ERROR("mod_netconf: creating rpc request failed");
         return (NULL);
     }
 
-    /* tell server to show all elements even if they have default values */
-#ifdef HAVE_WITHDEFAULTS_TAGGED
-    if (nc_rpc_capability_attr(rpc, NC_CAP_ATTR_WITHDEFAULTS_MODE, NCWD_MODE_ALL_TAGGED))
-#else
-    if (nc_rpc_capability_attr(rpc, NC_CAP_ATTR_WITHDEFAULTS_MODE, NCWD_MODE_NOTSET))
-    //if (nc_rpc_capability_attr(rpc, NC_CAP_ATTR_WITHDEFAULTS_MODE, NCWD_MODE_ALL))
-#endif
-    {
-        ERROR("mod_netconf: setting withdefaults failed");
-    }
-
-    res = netconf_op(session_key, rpc, &data);
+    res = netconf_op(session_key, rpc, strict, &data);
     nc_rpc_free(rpc);
     if (res != NULL) {
         (*err) = res;
@@ -1736,109 +1482,98 @@
              locked_session = locked_session->next);
         /* won't fail */
 
-        asprintf(&data_xml, "<get-config>%s</get-config>", data);
-        node = lyd_parse(locked_session->ctx, data_xml, LYD_XML, LYD_OPT_GETCONFIG | (strict ? LYD_OPT_STRICT : 0));
-        free(data_xml);
-        free(data);
-        if (!node) {
-            ERROR("Parsing <get-config> data failed.");
-            return NULL;
-        }
-
-        /* replace XML data with JSON data */
-        if (lyd_print_mem(&data, node, LYD_JSON)) {
+        /* print data into JSON */
+        if (lyd_print_mem(&data_json, data, LYD_JSON, LYP_WITHSIBLINGS)) {
             ERROR("Printing JSON <get-config> data failed.");
-            LY_TREE_FOR(node, sibling) {
-                lyd_free(sibling);
-            }
+            lyd_free_withsiblings(data);
             return NULL;
         }
 
         /* parse JSON data into cjson */
         pthread_mutex_lock(&json_lock);
-        data_cjson = json_tokener_parse_verbose(data, &tok_err);
+        data_cjson = json_tokener_parse_verbose(data_json, &tok_err);
         if (!data_cjson) {
             ERROR("Parsing JSON config failed (%s).", json_tokener_error_desc(tok_err));
             pthread_mutex_unlock(&json_lock);
-            LY_TREE_FOR(node, sibling) {
-                lyd_free(sibling);
-            }
-            free(data);
+            lyd_free_withsiblings(data);
+            free(data_json);
             return NULL;
         }
-        free(data);
+        free(data_json);
 
         /* go simultaneously through both trees and add metadata */
-        LY_TREE_FOR_SAFE(node, next, sibling) {
+        LY_TREE_FOR_SAFE(data, next, sibling) {
             node_add_metadata_recursive(sibling, NULL, data_cjson);
             lyd_free(sibling);
         }
 
-        data = strdup(json_object_to_json_string_ext(data_cjson, 0));
+        data_json = strdup(json_object_to_json_string_ext(data_cjson, 0));
         json_object_put(data_cjson);
         pthread_mutex_unlock(&json_lock);
     }
 
-    return (data);
+    return (data_json);
 }
 
 static char *
 netconf_getschema(unsigned int session_key, const char *identifier, const char *version, const char *format, json_object **err)
 {
-    nc_rpc* rpc;
-    char* data = NULL;
+    struct nc_rpc *rpc;
+    struct lyd_node *data = NULL;
     json_object *res = NULL;
+    char *model_data = NULL, *anyxml, *ptr, *ptr2;
 
     /* create requests */
-    rpc = nc_rpc_getschema(identifier, version, format);
+    rpc = nc_rpc_getschema(identifier, version, format, NC_PARAMTYPE_CONST);
     if (rpc == NULL) {
         ERROR("mod_netconf: creating rpc request failed");
         return (NULL);
     }
 
-    res = netconf_op(session_key, rpc, &data);
-    nc_rpc_free (rpc);
+    res = netconf_op(session_key, rpc, 0, &data);
+    nc_rpc_free(rpc);
     if (res != NULL) {
         (*err) = res;
     } else {
         (*err) = NULL;
+
+        if (data) {
+            lyxml_print_mem(&anyxml, ((struct lyd_node_anyxml *)data)->value, 0);
+
+            /* it's with the data root node, remove it */
+            if (anyxml) {
+                ptr = strchr(anyxml, '>');
+                ++ptr;
+
+                ptr2 = strrchr(anyxml, '<');
+
+                model_data = strndup(ptr, strlen(ptr) - strlen(ptr2));
+                free(anyxml);
+            }
+        }
     }
 
-    return (data);
+    return (model_data);
 }
 
 static char *
 netconf_get(unsigned int session_key, const char* filter, int strict, json_object **err)
 {
-    nc_rpc* rpc;
-    struct nc_filter *f = NULL;
-    char* data = NULL, *data_xml;
+    struct nc_rpc* rpc;
+    char* data_json = NULL;
     json_object *res = NULL, *data_cjson;
     enum json_tokener_error tok_err;
     struct session_with_mutex *locked_session;
-    struct lyd_node *node, *sibling, *next;
-
-    /* create filter if set */
-    if (filter != NULL) {
-        f = nc_filter_new(NC_FILTER_SUBTREE, filter);
-    }
+    struct lyd_node *data, *sibling, *next;
 
     /* create requests */
-    rpc = nc_rpc_get(f);
-    nc_filter_free(f);
+    rpc = nc_rpc_get(filter, 0, NC_PARAMTYPE_CONST);
     if (rpc == NULL) {
         ERROR("mod_netconf: creating rpc request failed");
         return (NULL);
     }
 
-    /* tell server to show all elements even if they have default values */
-    if (nc_rpc_capability_attr(rpc, NC_CAP_ATTR_WITHDEFAULTS_MODE, NCWD_MODE_NOTSET)) {
-    //if (nc_rpc_capability_attr(rpc, NC_CAP_ATTR_WITHDEFAULTS_MODE, NCWD_MODE_ALL)) {
-    //if (nc_rpc_capability_attr(rpc, NC_CAP_ATTR_WITHDEFAULTS_MODE, NCWD_MODE_ALL_TAGGED)) {
-        ERROR("mod_netconf: setting withdefaults failed");
-    }
-
-    res = netconf_op(session_key, rpc, &data);
+    res = netconf_op(session_key, rpc, strict, &data);
     nc_rpc_free(rpc);
     if (res != NULL) {
         (*err) = res;
@@ -1852,111 +1587,74 @@
              locked_session = locked_session->next);
         /* won't fail */
 
-        asprintf(&data_xml, "<get>%s</get>", data);
-        node = lyd_parse(locked_session->ctx, data_xml, LYD_XML, LYD_OPT_GET | (strict ? LYD_OPT_STRICT : 0));
-        free(data_xml);
-        free(data);
-        if (!node) {
-            ERROR("Parsing <get> data failed.");
-            return NULL;
-        }
-
-        /* replace XML data with JSON data */
-        if (lyd_print_mem(&data, node, LYD_JSON)) {
+        /* print JSON data */
+        if (lyd_print_mem(&data_json, data, LYD_JSON, LYP_WITHSIBLINGS)) {
             ERROR("Printing JSON <get> data failed.");
-            LY_TREE_FOR(node, sibling) {
-                lyd_free(sibling);
-            }
+            lyd_free_withsiblings(data);
             return NULL;
         }
 
         /* parse JSON data into cjson */
         pthread_mutex_lock(&json_lock);
-        data_cjson = json_tokener_parse_verbose(data, &tok_err);
+        data_cjson = json_tokener_parse_verbose(data_json, &tok_err);
         if (!data_cjson) {
             ERROR("Parsing JSON config failed (%s).", json_tokener_error_desc(tok_err));
             pthread_mutex_unlock(&json_lock);
-            LY_TREE_FOR(node, sibling) {
-                lyd_free(sibling);
-            }
-            free(data);
+            lyd_free_withsiblings(data);
+            free(data_json);
             return NULL;
         }
-        free(data);
+        free(data_json);
 
         /* go simultaneously through both trees and add metadata */
-        LY_TREE_FOR_SAFE(node, next, sibling) {
+        LY_TREE_FOR_SAFE(data, next, sibling) {
             node_add_metadata_recursive(sibling, NULL, data_cjson);
             lyd_free(sibling);
         }
 
-        data = strdup(json_object_to_json_string_ext(data_cjson, 0));
+        data_json = strdup(json_object_to_json_string_ext(data_cjson, 0));
         json_object_put(data_cjson);
         pthread_mutex_unlock(&json_lock);
     }
 
-    return data;
+    return data_json;
 }
 
 static json_object *
 netconf_copyconfig(unsigned int session_key, NC_DATASTORE source, NC_DATASTORE target, const char *config,
                    const char *uri_src, const char *uri_trg)
 {
-    nc_rpc* rpc;
+    struct nc_rpc* rpc;
     json_object *res = NULL;
 
     /* create requests */
-    if (source == NC_DATASTORE_CONFIG) {
-        if (target == NC_DATASTORE_URL) {
-            /* config, url */
-            rpc = nc_rpc_copyconfig(source, target, config, uri_trg);
-        } else {
-            /* config, datastore */
-            rpc = nc_rpc_copyconfig(source, target, config);
-        }
-    } else if (source == NC_DATASTORE_URL) {
-        if (target == NC_DATASTORE_URL) {
-            /* url, url */
-            rpc = nc_rpc_copyconfig(source, target, uri_src, uri_trg);
-        } else {
-            /* url, datastore */
-            rpc = nc_rpc_copyconfig(source, target, uri_src);
-        }
-    } else {
-        if (target == NC_DATASTORE_URL) {
-            /* datastore, url */
-            rpc = nc_rpc_copyconfig(source, target, uri_trg);
-        } else {
-            /* datastore, datastore */
-            rpc = nc_rpc_copyconfig(source, target);
-        }
-    }
+    rpc = nc_rpc_copy(target, uri_trg, source, (config ? config : uri_src), 0, NC_PARAMTYPE_CONST);
     if (rpc == NULL) {
         ERROR("mod_netconf: creating rpc request failed");
         return create_error_reply("Internal: Creating rpc request failed");
     }
 
-    res = netconf_op(session_key, rpc, NULL);
+    res = netconf_op(session_key, rpc, 0, NULL);
     nc_rpc_free(rpc);
 
     return res;
 }
 
 static json_object *
-netconf_editconfig(unsigned int session_key, NC_DATASTORE source, NC_DATASTORE target, NC_EDIT_DEFOP_TYPE defop,
-                   NC_EDIT_ERROPT_TYPE erropt, NC_EDIT_TESTOPT_TYPE testopt, const char *config_or_url)
+netconf_editconfig(unsigned int session_key, NC_DATASTORE target, NC_RPC_EDIT_DFLTOP defop,
+                   NC_RPC_EDIT_ERROPT erropt, NC_RPC_EDIT_TESTOPT testopt, const char *config_or_url)
 {
-    nc_rpc* rpc;
+    struct nc_rpc* rpc;
     json_object *res = NULL;
 
     /* create requests */
-    rpc = nc_rpc_editconfig(target, source, defop, erropt, testopt, config_or_url);
+    rpc = nc_rpc_edit(target, defop, testopt, erropt, config_or_url, NC_PARAMTYPE_CONST);
     if (rpc == NULL) {
         ERROR("mod_netconf: creating rpc request failed");
         return create_error_reply("Internal: Creating rpc request failed");
     }
 
-    res = netconf_op(session_key, rpc, NULL);
+    res = netconf_op(session_key, rpc, 0, NULL);
     nc_rpc_free (rpc);
 
     return res;
@@ -1965,25 +1663,25 @@
 static json_object *
 netconf_killsession(unsigned int session_key, const char *sid)
 {
-    nc_rpc *rpc;
+    struct nc_rpc *rpc;
     json_object *res = NULL;
 
     /* create requests */
-    rpc = nc_rpc_killsession(sid);
+    rpc = nc_rpc_kill(atoi(sid));
     if (rpc == NULL) {
         ERROR("mod_netconf: creating rpc request failed");
         return create_error_reply("Internal: Creating rpc request failed");
     }
 
-    res = netconf_op(session_key, rpc, NULL);
+    res = netconf_op(session_key, rpc, 0, NULL);
     nc_rpc_free(rpc);
     return res;
 }
 
 static json_object *
-netconf_onlytargetop(unsigned int session_key, NC_DATASTORE target, nc_rpc *(*op_func)(NC_DATASTORE))
+netconf_onlytargetop(unsigned int session_key, NC_DATASTORE target, struct nc_rpc *(*op_func)(NC_DATASTORE))
 {
-    nc_rpc* rpc;
+    struct nc_rpc* rpc;
     json_object *res = NULL;
 
     /* create requests */
@@ -1993,7 +1691,7 @@
         return create_error_reply("Internal: Creating rpc request failed");
     }
 
-    res = netconf_op(session_key, rpc, NULL);
+    res = netconf_op(session_key, rpc, 0, NULL);
     nc_rpc_free (rpc);
     return res;
 }
@@ -2001,19 +1699,15 @@
 static json_object *
 netconf_deleteconfig(unsigned int session_key, NC_DATASTORE target, const char *url)
 {
-    nc_rpc *rpc = NULL;
+    struct nc_rpc *rpc = NULL;
     json_object *res = NULL;
-    if (target != NC_DATASTORE_URL) {
-        rpc = nc_rpc_deleteconfig(target);
-    } else {
-        rpc = nc_rpc_deleteconfig(target, url);
-    }
+    rpc = nc_rpc_delete(target, url, NC_PARAMTYPE_CONST);
     if (rpc == NULL) {
         ERROR("mod_netconf: creating rpc request failed");
         return create_error_reply("Internal: Creating rpc request failed");
     }
 
-    res = netconf_op(session_key, rpc, NULL);
+    res = netconf_op(session_key, rpc, 0, NULL);
     nc_rpc_free (rpc);
     return res;
 }
@@ -2031,28 +1725,28 @@
 }
 
 static json_object *
-netconf_generic(unsigned int session_key, const char *content, char **data)
+netconf_generic(unsigned int session_key, const char *xml_content, struct lyd_node **data)
 {
-    nc_rpc* rpc = NULL;
+    struct nc_rpc* rpc = NULL;
     json_object *res = NULL;
 
     assert(!data || !*data);
 
     /* create requests */
-    rpc = nc_rpc_generic(content);
+    rpc = nc_rpc_generic_xml(xml_content, NC_PARAMTYPE_CONST);
     if (rpc == NULL) {
         ERROR("mod_netconf: creating rpc request failed");
         return create_error_reply("Internal: Creating rpc request failed");
     }
 
     /* get session where send the RPC */
-    res = netconf_op(session_key, rpc, data);
-    nc_rpc_free (rpc);
+    res = netconf_op(session_key, rpc, 0, data);
+    nc_rpc_free(rpc);
     return res;
 }
 
 static int
-node_add_metadata(struct lys_node *node, struct lys_module *module, json_object *parent)
+node_add_metadata(const struct lys_node *node, const struct lys_module *module, json_object *parent)
 {
     struct lys_module *cur_module;
     json_object *meta_obj;
@@ -2124,7 +1818,7 @@
 }
 
 static void
-node_add_metadata_recursive(struct lyd_node *data_tree, struct lys_module *module, json_object *data_json_parent)
+node_add_metadata_recursive(struct lyd_node *data_tree, const struct lys_module *module, json_object *data_json_parent)
 {
     struct lys_module *cur_module;
     struct lys_node *list_schema;
@@ -2203,7 +1897,7 @@
 }
 
 static void
-node_add_model_metadata(struct lys_module *module, json_object *parent)
+node_add_model_metadata(const struct lys_module *module, json_object *parent)
 {
     json_object *obj;
     char *str;
@@ -2216,9 +1910,9 @@
 }
 
 static void
-node_add_children_with_metadata_recursive(struct lys_node *node, struct lys_module *module, json_object *parent)
+node_add_children_with_metadata_recursive(const struct lys_node *node, const struct lys_module *module, json_object *parent)
 {
-    struct lys_module *cur_module;
+    const struct lys_module *cur_module;
     struct lys_node *child;
     json_object *node_json;
     char *json_name;
@@ -2269,8 +1963,8 @@
 static json_object *
 libyang_query(unsigned int session_key, const char *filter, int load_children)
 {
-    struct lys_node *node;
-    struct lys_module *module = NULL;
+    const struct lys_node *node;
+    const struct lys_module *module = NULL;
     struct session_with_mutex *locked_session;
     json_object *ret = NULL, *data;
 
@@ -2280,16 +1974,16 @@
         goto finish;
     }
 
-    session_user_activity(nc_session_get_user(locked_session->session));
+    session_user_activity(nc_session_get_username(locked_session->session));
 
     if (filter[0] == '/') {
-        node = ly_ctx_get_node(locked_session->ctx, filter);
+        node = ly_ctx_get_node(nc_session_get_ctx(locked_session->session), filter);
         if (!node) {
             ret = create_error_reply("Failed to resolve XPath filter node.");
             goto finish;
         }
     } else {
-        module = ly_ctx_get_module(locked_session->ctx, filter, NULL);
+        module = ly_ctx_get_module(nc_session_get_ctx(locked_session->session), filter, NULL);
         if (!module) {
             ret = create_error_reply("Failed to find model.");
             goto finish;
@@ -2337,9 +2031,9 @@
         goto finish;
     }
 
-    session_user_activity(nc_session_get_user(locked_session->session));
+    session_user_activity(nc_session_get_username(locked_session->session));
 
-    data_tree = lyd_parse(locked_session->ctx, config, LYD_JSON, LYD_OPT_STRICT);
+    data_tree = lyd_parse_mem(nc_session_get_ctx(locked_session->session), config, LYD_JSON, LYD_OPT_STRICT);
     if (!data_tree) {
         ERROR("Creating data tree failed.");
         ret = create_error_reply("Failed to create data tree from JSON config.");
@@ -2504,19 +2198,19 @@
     return -1;
 }
 
-NC_EDIT_TESTOPT_TYPE
+NC_RPC_EDIT_TESTOPT
 parse_testopt(const char *t)
 {
     if (strcmp(t, "notset") == 0) {
-        return NC_EDIT_TESTOPT_NOTSET;
+        return NC_RPC_EDIT_TESTOPT_UNKNOWN;
     } else if (strcmp(t, "testset") == 0) {
-        return NC_EDIT_TESTOPT_TESTSET;
+        return NC_RPC_EDIT_TESTOPT_TESTSET;
     } else if (strcmp(t, "set") == 0) {
-        return NC_EDIT_TESTOPT_SET;
+        return NC_RPC_EDIT_TESTOPT_SET;
     } else if (strcmp(t, "test") == 0) {
-        return NC_EDIT_TESTOPT_TEST;
+        return NC_RPC_EDIT_TESTOPT_TEST;
     }
-    return NC_EDIT_TESTOPT_ERROR;
+    return NC_RPC_EDIT_TESTOPT_UNKNOWN;
 }
 
 json_object *
@@ -2604,7 +2298,6 @@
     char *privkey = NULL;
     json_object *reply = NULL;
     unsigned int session_key = 0;
-    struct nc_cpblts* cpblts = NULL;
 
     DEBUG("Request: connect");
     pthread_mutex_lock(&json_lock);
@@ -2626,12 +2319,9 @@
         ERROR("Cannot connect - insufficient input.");
         session_key = 0;
     } else {
-        session_key = netconf_connect(host, port, user, pass, privkey, cpblts);
+        session_key = netconf_connect(host, port, user, pass, privkey);
         DEBUG("Session key: %u", session_key);
     }
-    if (cpblts != NULL) {
-        nc_cpblts_free(cpblts);
-    }
 
     GETSPEC_ERR_REPLY
 
@@ -2757,25 +2447,24 @@
 json_object *
 handle_op_editconfig(json_object *request, unsigned int session_key, int idx)
 {
-    NC_DATASTORE ds_type_s = -1;
     NC_DATASTORE ds_type_t = -1;
-    NC_EDIT_DEFOP_TYPE defop_type = NC_EDIT_DEFOP_NOTSET;
-    NC_EDIT_ERROPT_TYPE erropt_type = 0;
-    NC_EDIT_TESTOPT_TYPE testopt_type = NC_EDIT_TESTOPT_TESTSET;
+    NC_RPC_EDIT_DFLTOP defop_type = 0;
+    NC_RPC_EDIT_ERROPT erropt_type = 0;
+    NC_RPC_EDIT_TESTOPT testopt_type = NC_RPC_EDIT_TESTOPT_TESTSET;
     char *defop = NULL;
     char *erropt = NULL;
     char *config = NULL;
-    char *source = NULL;
     char *target = NULL;
     char *testopt = NULL;
     char *urisource = NULL;
     json_object *reply = NULL, *configs, *obj;
+    struct lyd_node *content;
+    struct session_with_mutex *locked_session;
 
     DEBUG("Request: edit-config (session %u)", session_key);
 
     pthread_mutex_lock(&json_lock);
     /* get parameters */
-    target = get_param_string(request, "target");
     if (json_object_object_get_ex(request, "configs", &configs) == FALSE) {
         pthread_mutex_unlock(&json_lock);
         reply = create_error_reply("Missing configs parameter.");
@@ -2784,7 +2473,7 @@
     obj = json_object_array_get_idx(configs, idx);
     config = strdup(json_object_get_string(obj));
 
-    source = get_param_string(request, "source");
+    target = get_param_string(request, "target");
     defop = get_param_string(request, "default-operation");
     erropt = get_param_string(request, "error-option");
     urisource = get_param_string(request, "uri-source");
@@ -2794,35 +2483,29 @@
     if (target != NULL) {
         ds_type_t = parse_datastore(target);
     }
-    if (source != NULL) {
-        ds_type_s = parse_datastore(source);
-    } else {
-        /* source is optional, default value is config */
-        ds_type_s = NC_DATASTORE_CONFIG;
-    }
 
     if (defop != NULL) {
         if (strcmp(defop, "merge") == 0) {
-            defop_type = NC_EDIT_DEFOP_MERGE;
+            defop_type = NC_RPC_EDIT_DFLTOP_MERGE;
         } else if (strcmp(defop, "replace") == 0) {
-            defop_type = NC_EDIT_DEFOP_REPLACE;
+            defop_type = NC_RPC_EDIT_DFLTOP_REPLACE;
         } else if (strcmp(defop, "none") == 0) {
-            defop_type = NC_EDIT_DEFOP_NONE;
+            defop_type = NC_RPC_EDIT_DFLTOP_NONE;
         } else {
             reply = create_error_reply("Invalid default-operation parameter.");
             goto finalize;
         }
     } else {
-        defop_type = NC_EDIT_DEFOP_NOTSET;
+        defop_type = NC_RPC_EDIT_DFLTOP_UNKNOWN;
     }
 
     if (erropt != NULL) {
         if (strcmp(erropt, "continue-on-error") == 0) {
-            erropt_type = NC_EDIT_ERROPT_CONT;
+            erropt_type = NC_RPC_EDIT_ERROPT_CONTINUE;
         } else if (strcmp(erropt, "stop-on-error") == 0) {
-            erropt_type = NC_EDIT_ERROPT_STOP;
+            erropt_type = NC_RPC_EDIT_ERROPT_STOP;
         } else if (strcmp(erropt, "rollback-on-error") == 0) {
-            erropt_type = NC_EDIT_ERROPT_ROLLBACK;
+            erropt_type = NC_RPC_EDIT_ERROPT_ROLLBACK;
         } else {
             reply = create_error_reply("Invalid error-option parameter.");
             goto finalize;
@@ -2831,30 +2514,35 @@
         erropt_type = 0;
     }
 
-    if ((int)ds_type_t == -1) {
-        reply = create_error_reply("Invalid target repository type requested.");
+    if ((config && urisource) || (!config && !urisource)) {
+        reply = create_error_reply("Invalid config and uri-source data parameters.");
         goto finalize;
     }
-    if (ds_type_s == NC_DATASTORE_CONFIG) {
-        if (config == NULL) {
-            reply = create_error_reply("Invalid config data parameter.");
+
+    if (config) {
+        locked_session = session_get_locked(session_key, NULL);
+        if (!locked_session) {
+            ERROR("Unknown session or locking failed.");
             goto finalize;
         }
-    } else if (ds_type_s == NC_DATASTORE_URL){
-        if (urisource == NULL) {
-            reply = create_error_reply("Invalid uri-source parameter.");
-            goto finalize;
-        }
+
+        content = lyd_parse_mem(nc_session_get_ctx(locked_session->session), config, LYD_JSON, LYD_OPT_EDIT);
+        session_unlock(locked_session);
+
+        free(config);
+        lyd_print_mem(&config, content, LYD_XML, LYP_WITHSIBLINGS);
+        lyd_free_withsiblings(content);
+    } else {
         config = urisource;
     }
 
     if (testopt != NULL) {
         testopt_type = parse_testopt(testopt);
     } else {
-        testopt_type = NC_EDIT_TESTOPT_TESTSET;
+        testopt_type = NC_RPC_EDIT_TESTOPT_TESTSET;
     }
 
-    reply = netconf_editconfig(session_key, ds_type_s, ds_type_t, defop_type, erropt_type, testopt_type, config);
+    reply = netconf_editconfig(session_key, ds_type_t, defop_type, erropt_type, testopt_type, config);
 
     CHECK_ERR_SET_REPLY
 
@@ -2862,7 +2550,6 @@
     CHECK_AND_FREE(defop);
     CHECK_AND_FREE(erropt);
     CHECK_AND_FREE(config);
-    CHECK_AND_FREE(source);
     CHECK_AND_FREE(urisource);
     CHECK_AND_FREE(target);
     CHECK_AND_FREE(testopt);
@@ -2881,6 +2568,8 @@
     char *uri_src = NULL;
     char *uri_trg = NULL;
     json_object *reply = NULL, *configs, *obj;
+    struct lyd_node *content;
+    struct session_with_mutex *locked_session;
 
     DEBUG("Request: copy-config (session %u)", session_key);
 
@@ -2935,6 +2624,22 @@
             uri_trg = "";
         }
     }
+
+    if (config) {
+        locked_session = session_get_locked(session_key, NULL);
+        if (!locked_session) {
+            ERROR("Unknown session or locking failed.");
+            goto finalize;
+        }
+
+        content = lyd_parse_mem(nc_session_get_ctx(locked_session->session), config, LYD_JSON, LYD_OPT_CONFIG);
+        session_unlock(locked_session);
+
+        free(config);
+        lyd_print_mem(&config, content, LYD_XML, LYP_WITHSIBLINGS);
+        lyd_free_withsiblings(content);
+    }
+
     reply = netconf_copyconfig(session_key, ds_type_s, ds_type_t, config, uri_src, uri_trg);
 
     CHECK_ERR_SET_REPLY
@@ -3125,8 +2830,9 @@
 handle_op_generic(json_object *request, unsigned int session_key, int idx)
 {
     json_object *reply = NULL, *contents, *obj;
-    char *config = NULL;
-    char *data = NULL;
+    char *content = NULL, *str;
+    struct lyd_node *data = NULL, *node_content;
+    struct session_with_mutex *locked_session;
 
     DEBUG("Request: generic request (session %u)", session_key);
 
@@ -3142,10 +2848,23 @@
         reply = create_error_reply("Contents array parameter shorter than sessions.");
         goto finalize;
     }
-    config = strdup(json_object_get_string(obj));
+    content = strdup(json_object_get_string(obj));
     pthread_mutex_unlock(&json_lock);
 
-    reply = netconf_generic(session_key, config, &data);
+    locked_session = session_get_locked(session_key, NULL);
+    if (!locked_session) {
+        ERROR("Unknown session or locking failed.");
+        goto finalize;
+    }
+
+    node_content = lyd_parse_mem(nc_session_get_ctx(locked_session->session), content, LYD_JSON, LYD_OPT_RPC);
+    session_unlock(locked_session);
+
+    free(content);
+    lyd_print_mem(&content, node_content, LYD_XML, LYP_WITHSIBLINGS);
+    lyd_free_withsiblings(node_content);
+
+    reply = netconf_generic(session_key, content, &data);
     if (reply == NULL) {
         GETSPEC_ERR_REPLY
         if (err_reply != NULL) {
@@ -3159,13 +2878,15 @@
             json_object_object_add(reply, "type", json_object_new_int(REPLY_OK));
             pthread_mutex_unlock(&json_lock);
         } else {
-            reply = create_data_reply(data);
-            free(data);
+            lyd_print_mem(&str, data, LYD_JSON, LYP_WITHSIBLINGS);
+            lyd_free_withsiblings(data);
+            reply = create_data_reply(str);
+            free(str);
         }
     }
 
 finalize:
-    CHECK_AND_FREE(config);
+    CHECK_AND_FREE(content);
     return reply;
 }
 
@@ -3228,7 +2949,7 @@
         DEBUG("LOCK mutex %s", __func__);
         pthread_mutex_lock(&locked_session->lock);
         DEBUG("creating temporary NC session.");
-        temp_session = nc_session_connect_channel(locked_session->session, NULL);
+        temp_session = nc_connect_ssh_channel(locked_session->session, NULL);
         if (temp_session != NULL) {
             prepare_status_message(locked_session, temp_session);
             DEBUG("closing temporal NC session.");
@@ -3260,8 +2981,14 @@
 }
 
 void
-notification_history(time_t eventtime, const char *content)
+notification_history(struct nc_session *session, const struct nc_notif *notif)
 {
+    time_t eventtime;
+    char *content;
+    (void)session;
+
+    eventtime = nc_datetime2time(notif->datetime);
+
     json_object *notif_history_array = (json_object *)pthread_getspecific(notif_history_key);
     if (notif_history_array == NULL) {
         ERROR("No list of notification history found.");
@@ -3269,14 +2996,19 @@
     }
     DEBUG("Got notification from history %lu.", (long unsigned)eventtime);
     pthread_mutex_lock(&json_lock);
-    json_object *notif = json_object_new_object();
-    if (notif == NULL) {
+    json_object *notif_obj = json_object_new_object();
+    if (notif_obj == NULL) {
         ERROR("Could not allocate memory for notification (json).");
         goto failed;
     }
-    json_object_object_add(notif, "eventtime", json_object_new_int64(eventtime));
-    json_object_object_add(notif, "content", json_object_new_string(content));
-    json_object_array_add(notif_history_array, notif);
+    lyd_print_mem(&content, notif->tree, LYD_JSON, 0);
+
+    json_object_object_add(notif_obj, "eventtime", json_object_new_int64(eventtime));
+    json_object_object_add(notif_obj, "content", json_object_new_string(content));
+
+    free(content);
+
+    json_object_array_add(notif_history_array, notif_obj);
 failed:
     pthread_mutex_unlock(&json_lock);
 }
@@ -3288,7 +3020,7 @@
     json_object *js_tmp = NULL;
     struct session_with_mutex *locked_session = NULL;
     struct nc_session *temp_session = NULL;
-    nc_rpc *rpc = NULL;
+    struct nc_rpc *rpc = NULL;
     time_t start = 0;
     time_t stop = 0;
     int64_t from = 0, to = 0;
@@ -3327,9 +3059,9 @@
             ERROR("Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
         }
         DEBUG("creating temporal NC session.");
-        temp_session = nc_session_connect_channel(locked_session->session, NULL);
+        temp_session = nc_connect_ssh_channel(locked_session->session, NULL);
         if (temp_session != NULL) {
-            rpc = nc_rpc_subscribe(NULL /* stream */, NULL /* filter */, &start, &stop);
+            rpc = nc_rpc_subscribe(NULL, NULL, nc_time2datetime(start, NULL), nc_time2datetime(stop, NULL), NC_PARAMTYPE_CONST);
             if (rpc == NULL) {
                 DEBUG("UNLOCK mutex %s", __func__);
                 pthread_mutex_unlock(&locked_session->lock);
@@ -3361,7 +3093,7 @@
                 ERROR("notif_history: cannot set thread-specific hash value.");
             }
 
-            ncntf_dispatch_receive(temp_session, notification_history);
+            nc_recv_notif_dispatch(temp_session, notification_history);
 
             pthread_mutex_lock(&json_lock);
             reply = json_object_new_object();
@@ -3398,7 +3130,7 @@
     json_object *reply = NULL;
     char *target = NULL;
     char *url = NULL;
-    nc_rpc *rpc = NULL;
+    struct nc_rpc *rpc = NULL;
     NC_DATASTORE target_ds;
 
     DEBUG("Request: validate datastore (session %u)", session_key);
@@ -3416,21 +3148,14 @@
 
     /* validation */
     target_ds = parse_datastore(target);
-    if (target_ds == NC_DATASTORE_URL) {
-        if (url != NULL) {
-            rpc = nc_rpc_validate(target_ds, url);
-        }
-    } else if ((target_ds == NC_DATASTORE_RUNNING) || (target_ds == NC_DATASTORE_STARTUP)
-            || (target_ds == NC_DATASTORE_CANDIDATE)) {
-        rpc = nc_rpc_validate(target_ds);
-    }
+    rpc = nc_rpc_validate(target_ds, url, NC_PARAMTYPE_CONST);
     if (rpc == NULL) {
         DEBUG("mod_netconf: creating rpc request failed");
         reply = create_error_reply("Creation of RPC request failed.");
         goto finalize;
     }
 
-    if ((reply = netconf_op(session_key, rpc, NULL)) == NULL) {
+    if ((reply = netconf_op(session_key, rpc, 0, NULL)) == NULL) {
         CHECK_ERR_SET_REPLY
 
         if (reply == NULL) {
@@ -3490,6 +3215,8 @@
 {
     json_object *reply = NULL, *configs, *obj;
     char *config = NULL;
+    struct lyd_node *content;
+    struct session_with_mutex *locked_session;
 
     DEBUG("Request: merge (session %u)", session_key);
 
@@ -3508,6 +3235,19 @@
     config = strdup(json_object_get_string(obj));
     pthread_mutex_unlock(&json_lock);
 
+    locked_session = session_get_locked(session_key, NULL);
+    if (!locked_session) {
+        ERROR("Unknown session or locking failed.");
+        goto finalize;
+    }
+
+    content = lyd_parse_mem(nc_session_get_ctx(locked_session->session), config, LYD_JSON, LYD_OPT_DATA);
+    session_unlock(locked_session);
+
+    free(config);
+    lyd_print_mem(&config, content, LYD_XML, LYP_WITHSIBLINGS);
+    lyd_free_withsiblings(content);
+
     reply = libyang_merge(session_key, config);
 
     CHECK_ERR_SET_REPLY
@@ -3769,7 +3509,7 @@
         next_session = locked_session->next;
 
         /* close_and_free_session handles locking on its own */
-        DEBUG("Closing NETCONF session %u (SID %s).", locked_session->session_key, nc_session_get_id(locked_session->session));
+        DEBUG("Closing NETCONF session %u (SID %u).", locked_session->session_key, nc_session_get_id(locked_session->session));
         close_and_free_session(locked_session);
     }
     netconf_sessions_list = NULL;
@@ -3801,7 +3541,7 @@
         }
         pthread_mutex_lock(&locked_session->lock);
         if ((current_time - locked_session->last_activity) > ACTIVITY_TIMEOUT) {
-            DEBUG("Closing NETCONF session %u (SID %s).", locked_session->session_key, nc_session_get_id(locked_session->session));
+            DEBUG("Closing NETCONF session %u (SID %u).", locked_session->session_key, nc_session_get_id(locked_session->session));
 
             /* close_and_free_session handles locking on its own */
             close_and_free_session(locked_session);
@@ -3938,15 +3678,14 @@
 
     /* setup libnetconf's callbacks */
     nc_verbosity(NC_VERB_DEBUG);
-    nc_callback_print(clb_print);
-    nc_callback_ssh_host_authenticity_check(netconf_callback_ssh_hostkey_check);
-    nc_callback_sshauth_interactive(netconf_callback_sshauth_interactive);
-    nc_callback_sshauth_password(netconf_callback_sshauth_password);
-    nc_callback_sshauth_passphrase(netconf_callback_sshauth_passphrase);
-    nc_callback_error_reply(netconf_callback_error_process);
+    nc_set_print_clb(clb_print);
+    nc_client_ssh_set_auth_hostkey_check_clb(netconf_callback_ssh_hostkey_check);
+    nc_client_ssh_set_auth_interactive_clb(netconf_callback_sshauth_interactive);
+    nc_client_ssh_set_auth_password_clb(netconf_callback_sshauth_password);
+    nc_client_ssh_set_auth_privkey_passphrase_clb(netconf_callback_sshauth_passphrase);
 
     /* disable publickey authentication */
-    nc_ssh_pref(NC_SSH_AUTH_PUBLIC_KEYS, -1);
+    nc_client_ssh_set_auth_pref(NC_SSH_AUTH_PUBLICKEY, -1);
 
     /* create mutex protecting session list */
     pthread_rwlockattr_init(&lock_attrs);
diff --git a/src/netopeerguid.h b/src/netopeerguid.h
index 15d4ce1..b59ab6c 100644
--- a/src/netopeerguid.h
+++ b/src/netopeerguid.h
@@ -46,8 +46,8 @@
  * if advised of the possibility of such damage.
  *
  */
-#ifndef __MOD_NETCONF_COMMON_H
-#define __MOD_NETCONF_COMMON_H
+#ifndef _NETOPEERGUID_H
+#define _NETOPEERGUID_H
 
 #include <pthread.h>
 #include <json/json.h>
@@ -74,7 +74,6 @@
     char ntfc_subscribed; /**< 0 when notifications are not subscribed */
     char closed; /**< 0 when session is terminated */
     time_t last_activity;
-    struct ly_ctx *ctx;
     pthread_mutex_t lock; /**< mutex protecting the session from multiple access */
 
     struct session_with_mutex *prev;
@@ -130,7 +129,7 @@
 void clean_err_reply();
 void free_err_reply();
 
-NC_MSG_TYPE netconf_send_recv_timed(struct nc_session *session, nc_rpc *rpc,
-                       int timeout, nc_reply **reply);
+NC_MSG_TYPE netconf_send_recv_timed(struct nc_session *session, struct nc_rpc *rpc, int timeout,
+                                    int strict, struct nc_reply **reply);
 
 #endif
diff --git a/src/notification_server.c b/src/notification_server.c
index 19d8934..2143c9b 100644
--- a/src/notification_server.c
+++ b/src/notification_server.c
@@ -30,7 +30,7 @@
 #include <assert.h>
 #include <pthread.h>
 #include <errno.h>
-#include <libnetconf.h>
+#include <nc_client.h>
 #include <libwebsockets.h>
 
 #include "notification_server.h"
@@ -271,22 +271,22 @@
 		return (NULL);
 	}
 	for (locked_session = netconf_sessions_list;
-         locked_session && strcmp(nc_session_get_id(locked_session->session), session_id);
+         locked_session && (nc_session_get_id(locked_session->session) == (unsigned)atoi(session_id));
          locked_session = locked_session->next);
 	return locked_session;
 }
 
 /* rpc parameter is freed after the function call */
-static int send_recv_process(struct nc_session *session, const char* UNUSED(operation), nc_rpc* rpc)
+static int send_recv_process(struct nc_session *session, const char* UNUSED(operation), struct nc_rpc* rpc)
 {
-	nc_reply *reply = NULL;
+	struct nc_reply *reply = NULL;
 	char *data = NULL;
 	int ret = EXIT_SUCCESS;
 
 	/* send the request and get the reply */
-	switch (nc_session_send_recv(session, rpc, &reply)) {
-	case NC_MSG_UNKNOWN:
-		if (nc_session_get_status(session) != NC_SESSION_STATUS_WORKING) {
+	switch (netconf_send_recv_timed(session, rpc, 50000, 0, &reply)) {
+	case NC_MSG_ERROR:
+		if (nc_session_get_status(session) != NC_STATUS_RUNNING) {
 			ERROR("notifications: receiving rpc-reply failed.");
 			//cmd_disconnect(NULL);
 			ret = EXIT_FAILURE;
@@ -299,14 +299,15 @@
 		/* error occurred, but processed by callback */
 		break;
 	case NC_MSG_REPLY:
-		switch (nc_reply_get_type(reply)) {
-		case NC_REPLY_OK:
+		switch (reply->type) {
+		case NC_RPL_OK:
 			break;
-		case NC_REPLY_DATA:
-			DEBUG("notifications: recv: %s.", data = nc_reply_get_data (reply));
-			free(data);
+		case NC_RPL_DATA:
+            lyd_print_mem(&data, ((struct nc_reply_data *)reply)->data, LYD_JSON, 0);
+			DEBUG("notifications: recv: %s.", data);
+            free(data);
 			break;
-		case NC_REPLY_ERROR:
+		case NC_RPL_ERROR:
 			/* wtf, you shouldn't be here !?!? */
 			DEBUG("notifications: operation failed, but rpc-error was not processed.");
 			ret = EXIT_FAILURE;
@@ -333,11 +334,17 @@
  * \param [in] eventtime - time when notification occured
  * \param [in] content - content of notification
  */
-static void notification_fileprint (time_t eventtime, const char* content)
+static void notification_fileprint(struct nc_session *session, const struct nc_notif *notif)
 {
+    time_t eventtime;
 	struct session_with_mutex *target_session = NULL;
 	notification_t *ntf = NULL;
 	const char *session_id = NULL;
+    char *content;
+    (void)session;
+
+    eventtime = nc_datetime2time(notif->datetime);
+    lyd_print_mem(&content, notif->tree, LYD_JSON, 0);
 
 	DEBUG("Accepted notif: %lu %s\n", (unsigned long int) eventtime, content);
 
@@ -345,12 +352,14 @@
 	DEBUG("notification: fileprint getspecific (%s)", session_id);
 	if (pthread_rwlock_wrlock(&session_lock) != 0) {
 		ERROR("notifications: Error while locking rwlock");
+        free(content);
 		return;
 	}
 	DEBUG("Get session with mutex from key %s.", session_id);
 	target_session = get_ncsession_from_sid(session_id);
 	if (target_session == NULL) {
 		ERROR("notifications: no session found last_session_key (%s)", session_id);
+        free(content);
 		goto unlock_glob;
 	}
 	if (pthread_mutex_lock(&target_session->lock) != 0) {
@@ -368,10 +377,11 @@
     }
 	if (ntf == NULL) {
 		ERROR("notifications: Failed to allocate element ");
+        free(content);
 		goto unlock_all;
 	}
 	ntf->eventtime = eventtime;
-	ntf->content = strdup(content);
+	ntf->content = content;
 
 	DEBUG("added notif to queue %u (%s)", (unsigned int) ntf->eventtime, "notification");
 
@@ -400,7 +410,7 @@
 	}
 
 	DEBUG("notifications: dispatching");
-	ncntf_dispatch_receive(config->session, notification_fileprint);
+	nc_recv_notif_dispatch(config->session, notification_fileprint);
 	DEBUG("notifications: ended thread for libnetconf notifications");
 	if (config->session_id != NULL) {
 		free(config->session_id);
@@ -416,9 +426,8 @@
 {
 	time_t start = -1;
 	time_t stop = -1;
-	struct nc_filter *filter = NULL;
 	char *stream = NULL;
-	nc_rpc *rpc = NULL;
+	struct nc_rpc *rpc = NULL;
 	pthread_t thread;
 	struct ntf_thread_config *tconfig;
 	struct nc_session *session;
@@ -444,11 +453,6 @@
 		goto operation_failed;
 	}
 
-	/* check if notifications are allowed on this session */
-	if (nc_session_notif_allowed(session) == 0) {
-		ERROR("notifications: Notification subscription is not allowed on this session.");
-		goto operation_failed;
-	}
 	/* check times */
 	if (start != -1 && stop != -1 && start > stop) {
 		ERROR("notifications: Subscription start time must be lower than the end time.");
@@ -457,8 +461,8 @@
 
 	DEBUG("Prepare to execute subscription.");
 	/* create requests */
-	rpc = nc_rpc_subscribe(stream, filter, (start_time == -1)?NULL:&start, (stop_time == 0)?NULL:&stop);
-	nc_filter_free(filter);
+	rpc = nc_rpc_subscribe(stream, NULL, (start_time == -1) ? NULL : nc_time2datetime(start, NULL),
+                           (stop_time == 0) ? NULL : nc_time2datetime(stop, NULL), NC_PARAMTYPE_CONST);
 	if (rpc == NULL) {
 		ERROR("notifications: creating an rpc request failed.");
 		goto operation_failed;