session CHANGE generalize setting of the session's capabilities
instead of setter for the specific, interleave, capability, allow
to set a generic capbility as a string.
diff --git a/src/session.c b/src/session.c
index 4bdd379..28741db 100644
--- a/src/session.c
+++ b/src/session.c
@@ -534,6 +534,27 @@
static void
add_cpblt(struct ly_ctx *ctx, const char *capab, const char ***cpblts, int *size, int *count)
{
+ size_t len;
+ int i;
+ char *p;
+
+ if (capab) {
+ /* check if already present */
+ p = strchr(capab, '?');
+ if (p) {
+ len = p - capab;
+ } else {
+ len = strlen(capab);
+ }
+ for (i = 0; i < *count; i++) {
+ if (!strncmp((*cpblts)[i], capab, len)) {
+ /* already present, do not duplicate it */
+ return;
+ }
+ }
+ }
+
+ /* add another capability */
if (*count == *size) {
*size += 5;
*cpblts = nc_realloc(*cpblts, *size * sizeof **cpblts);
@@ -559,6 +580,7 @@
const char **cpblts;
const struct lys_module *mod;
int size = 10, count, feat_count = 0, dev_count = 0, i, str_len;
+ unsigned int u;
#define NC_CPBLT_BUF_LEN 512
char str[NC_CPBLT_BUF_LEN];
@@ -654,12 +676,9 @@
}
}
- mod = ly_ctx_get_module(ctx, "nc-notifications", NULL);
- if (mod) {
- add_cpblt(ctx, "urn:ietf:params:netconf:capability:notification:1.0", &cpblts, &size, &count);
- if (server_opts.interleave_capab) {
- add_cpblt(ctx, "urn:ietf:params:netconf:capability:interleave:1.0", &cpblts, &size, &count);
- }
+ /* other capabilities */
+ for (u = 0; u < server_opts.capabilities_count; u++) {
+ add_cpblt(ctx, server_opts.capabilities[u], &cpblts, &size, &count);
}
/* models */
diff --git a/src/session_p.h b/src/session_p.h
index c4fe1bd..7b135b4 100644
--- a/src/session_p.h
+++ b/src/session_p.h
@@ -141,7 +141,8 @@
/* ACCESS unlocked */
NC_WD_MODE wd_basic_mode;
int wd_also_supported;
- int interleave_capab;
+ unsigned int capabilities_count;
+ const char **capabilities;
/* ACCESS unlocked */
uint16_t hello_timeout;
diff --git a/src/session_server.c b/src/session_server.c
index 45d588c..a71242f 100644
--- a/src/session_server.c
+++ b/src/session_server.c
@@ -452,6 +452,12 @@
API void
nc_server_destroy(void)
{
+ unsigned int i;
+
+ for (i = 0; i < server_opts.capabilities_count; i++) {
+ lydict_remove(server_opts.ctx, server_opts.capabilities[i]);
+ }
+ free(server_opts.capabilities);
pthread_spin_destroy(&server_opts.sid_lock);
#if defined(NC_ENABLED_SSH) || defined(NC_ENABLED_TLS)
@@ -495,20 +501,26 @@
}
}
-API void
-nc_server_set_capab_interleave(int interleave_support)
-{
- if (interleave_support) {
- server_opts.interleave_capab = 1;
- } else {
- server_opts.interleave_capab = 0;
- }
-}
-
API int
-nc_server_get_capab_interleave(void)
+nc_server_set_capability(const char *value)
{
- return server_opts.interleave_capab;
+ const char **new;
+
+ if (!value || !value[0]) {
+ ERRARG("value must not be empty");
+ return EXIT_FAILURE;
+ }
+
+ server_opts.capabilities_count++;
+ new = realloc(server_opts.capabilities, server_opts.capabilities_count * sizeof *server_opts.capabilities);
+ if (!new) {
+ ERRMEM;
+ return EXIT_FAILURE;
+ }
+ server_opts.capabilities = new;
+ server_opts.capabilities[server_opts.capabilities_count - 1] = lydict_insert(server_opts.ctx, value, 0);
+
+ return EXIT_SUCCESS;
}
API void
diff --git a/src/session_server.h b/src/session_server.h
index a7f3653..45120ac 100644
--- a/src/session_server.h
+++ b/src/session_server.h
@@ -109,24 +109,16 @@
void nc_server_get_capab_withdefaults(NC_WD_MODE *basic_mode, int *also_supported);
/**
- * @brief Set the interleave capability.
+ * @brief Set capability of the server.
*
- * For the capability to be actually advertised, the server context must also
- * include the nc-notifications model.
+ * Capability can be used when some behavior or extension of the server is not defined
+ * as a YANG module. The provided value will be advertised in the server's \<hello\>
+ * messages. Note, that libnetconf only checks that the provided value is non-empty
+ * string.
*
- * Changing this option has the same ill effects as changing capabilities while
- * sessions are already established.
- *
- * @param[in] interleave_support 1 to suport interleave, 0 to not.
+ * @param[in] value Capability string to be advertised in server\s \<hello\> messages.
*/
-void nc_server_set_capab_interleave(int interleave_support);
-
-/**
- * @brief Get the interleave capability state.
- *
- * @return 1 for supported, 0 for not supported.
- */
-int nc_server_get_capab_interleave(void);
+int nc_server_set_capability(const char *value);
/**
* @brief Set server timeout for receiving a hello message.