int netopeer_transapi_init_ssh(void) {
	xmlDocPtr doc;
	struct nc_err* error = NULL;
	const char* str_err;

	nc_verb_verbose("Setting the default configuration for the cfgnetopeer module SSH...");

	netopeer_options.ssh_opts = calloc(1, sizeof(struct np_options_ssh));
	pthread_mutex_init(&netopeer_options.ssh_opts->client_keys_lock, NULL);

	doc = xmlReadDoc(BAD_CAST "<netopeer xmlns=\"urn:cesnet:tmc:netopeer:1.0\"><ssh><server-keys><rsa-key>/etc/ssh/ssh_host_rsa_key</rsa-key></server-keys><password-auth-enabled>true</password-auth-enabled><auth-attempts>3</auth-attempts><auth-timeout>10</auth-timeout></ssh></netopeer>",
		NULL, NULL, 0);
	if (doc == NULL) {
		nc_verb_error("Unable to parse the default cfgnetopeer SSH configuration.");
		return EXIT_FAILURE;
	}

	if (callback_n_netopeer_n_ssh_n_server_keys_n_rsa_key(NULL, XMLDIFF_ADD, NULL, doc->children->children->children->children, &error) != EXIT_SUCCESS) {
		if (error != NULL) {
			str_err = nc_err_get(error, NC_ERR_PARAM_MSG);
			if (str_err != NULL) {
				nc_verb_error(str_err);
			}
			nc_err_free(error);
		}
		xmlFreeDoc(doc);
		return EXIT_FAILURE;
	}

	if (callback_n_netopeer_n_ssh_n_password_auth_enabled(NULL, XMLDIFF_ADD, NULL, doc->children->children->children->next, &error) != EXIT_SUCCESS) {
		if (error != NULL) {
			str_err = nc_err_get(error, NC_ERR_PARAM_MSG);
			if (str_err != NULL) {
				nc_verb_error(str_err);
			}
			nc_err_free(error);
		}
		xmlFreeDoc(doc);
		return EXIT_FAILURE;
	}

	if (callback_n_netopeer_n_ssh_n_auth_attempts(NULL, XMLDIFF_ADD, NULL, doc->children->children->children->next->next, &error) != EXIT_SUCCESS) {
		if (error != NULL) {
			str_err = nc_err_get(error, NC_ERR_PARAM_MSG);
			if (str_err != NULL) {
				nc_verb_error(str_err);
			}
			nc_err_free(error);
		}
		xmlFreeDoc(doc);
		return EXIT_FAILURE;
	}

	if (callback_n_netopeer_n_ssh_n_auth_timeout(NULL, XMLDIFF_ADD, NULL, doc->children->children->children->next->next->next, &error) != EXIT_SUCCESS) {
		if (error != NULL) {
			str_err = nc_err_get(error, NC_ERR_PARAM_MSG);
			if (str_err != NULL) {
				nc_verb_error(str_err);
			}
			nc_err_free(error);
		}
		xmlFreeDoc(doc);
		return EXIT_FAILURE;
	}

	xmlFreeDoc(doc);
	return EXIT_SUCCESS;
}
/**
 * @brief Initialize plugin after loaded and before any other functions are called.

 * This function should not apply any configuration data to the controlled device. If no
 * running is returned (it stays *NULL), complete startup configuration is consequently
 * applied via module callbacks. When a running configuration is returned, libnetconf
 * then applies (via module's callbacks) only the startup configuration data that
 * differ from the returned running configuration data.

 * Please note, that copying startup data to the running is performed only after the
 * libnetconf's system-wide close - see nc_close() function documentation for more
 * information.

 * @param[out] running	Current configuration of managed device.

 * @return EXIT_SUCCESS or EXIT_FAILURE
 */
int netopeer_transapi_init(xmlDocPtr* UNUSED(running)) {
	xmlDocPtr doc;
	struct nc_err* error = NULL;
	const char* str_err;

	nc_verb_verbose("Setting the default configuration for the cfgnetopeer module...");

	doc = xmlReadDoc(BAD_CAST "<netopeer xmlns=\"urn:cesnet:tmc:netopeer:1.0\"><hello-timeout>600</hello-timeout><idle-timeout>3600</idle-timeout><max-sessions>8</max-sessions><response-time>50</response-time><client-removal-time>10</client-removal-time></netopeer>",
		NULL, NULL, 0);
	if (doc == NULL) {
		nc_verb_error("Unable to parse the default cfgnetopeer configuration.");
		return EXIT_FAILURE;
	}

	if (callback_n_netopeer_n_hello_timeout(NULL, XMLDIFF_ADD, NULL, doc->children->children, &error) != EXIT_SUCCESS) {
		if (error != NULL) {
			str_err = nc_err_get(error, NC_ERR_PARAM_MSG);
			if (str_err != NULL) {
				nc_verb_error(str_err);
			}
			nc_err_free(error);
		}
		xmlFreeDoc(doc);
		return EXIT_FAILURE;
	}

	if (callback_n_netopeer_n_idle_timeout(NULL, XMLDIFF_ADD, NULL, doc->children->children->next, &error) != EXIT_SUCCESS) {
		if (error != NULL) {
			str_err = nc_err_get(error, NC_ERR_PARAM_MSG);
			if (str_err != NULL) {
				nc_verb_error(str_err);
			}
			nc_err_free(error);
		}
		xmlFreeDoc(doc);
		return EXIT_FAILURE;
	}

	if (callback_n_netopeer_n_max_sessions(NULL, XMLDIFF_ADD, NULL, doc->children->children->next->next, &error) != EXIT_SUCCESS) {
		if (error != NULL) {
			str_err = nc_err_get(error, NC_ERR_PARAM_MSG);
			if (str_err != NULL) {
				nc_verb_error(str_err);
			}
			nc_err_free(error);
		}
		xmlFreeDoc(doc);
		return EXIT_FAILURE;
	}

	if (callback_n_netopeer_n_response_time(NULL, XMLDIFF_ADD, NULL, doc->children->children->next->next->next, &error) != EXIT_SUCCESS) {
		if (error != NULL) {
			str_err = nc_err_get(error, NC_ERR_PARAM_MSG);
			if (str_err != NULL) {
				nc_verb_error(str_err);
			}
			nc_err_free(error);
		}
		xmlFreeDoc(doc);
		return EXIT_FAILURE;
	}

	if (callback_n_netopeer_n_client_removal_time(NULL, XMLDIFF_ADD, NULL, doc->children->children->next->next->next->next, &error) != EXIT_SUCCESS) {
		if (error != NULL) {
			str_err = nc_err_get(error, NC_ERR_PARAM_MSG);
			if (str_err != NULL) {
				nc_verb_error(str_err);
			}
			nc_err_free(error);
		}
		xmlFreeDoc(doc);
		return EXIT_FAILURE;
	}
	xmlFreeDoc(doc);

#ifdef NP_SSH
	if (ncds_feature_isenabled("cfgnetopeer", "ssh") && (netopeer_transapi_init_ssh() != EXIT_SUCCESS)) {
		return EXIT_FAILURE;
	}
#endif
#ifdef NP_TLS
	if (ncds_feature_isenabled("cfgnetopeer", "tls") && (netopeer_transapi_init_tls() != EXIT_SUCCESS)) {
		return EXIT_FAILURE;
	}
#endif

	return EXIT_SUCCESS;
}