blob: 064faf4beb0c5b07ed321425a472d0788d633272 [file] [log] [blame]
Michal Vasko7bcb48e2016-01-15 10:28:54 +01001/**
2 * \file messages.c
3 * \author Radek Krejci <rkrejci@cesnet.cz>
4 * \brief libnetconf2 - NETCONF messages functions
5 *
6 * Copyright (c) 2015 CESNET, z.s.p.o.
7 *
Radek Krejci9b81f5b2016-02-24 13:14:49 +01008 * This source code is licensed under BSD 3-Clause License (the "License").
9 * You may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
Michal Vaskoafd416b2016-02-25 14:51:46 +010011 *
Radek Krejci9b81f5b2016-02-24 13:14:49 +010012 * https://opensource.org/licenses/BSD-3-Clause
Michal Vasko7bcb48e2016-01-15 10:28:54 +010013 */
14
Radek Krejci36d2ee42017-10-13 13:55:59 +020015#include <assert.h>
Michal Vasko7bcb48e2016-01-15 10:28:54 +010016#include <ctype.h>
17#include <stdlib.h>
18#include <string.h>
19#include <stdarg.h>
20
21#include <libyang/libyang.h>
22
23#include "libnetconf.h"
Michal Vasko7bcb48e2016-01-15 10:28:54 +010024
25const char *rpcedit_dfltop2str[] = {NULL, "merge", "replace", "none"};
26const char *rpcedit_testopt2str[] = {NULL, "test-then-set", "set", "test-only"};
27const char *rpcedit_erropt2str[] = {NULL, "stop-on-error", "continue-on-error", "rollback-on-error"};
28
29API NC_RPC_TYPE
30nc_rpc_get_type(const struct nc_rpc *rpc)
31{
Michal Vasko7f1c78b2016-01-19 09:52:14 +010032 if (!rpc) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020033 ERRARG("rpc");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010034 return 0;
35 }
36
Michal Vasko7bcb48e2016-01-15 10:28:54 +010037 return rpc->type;
38}
39
40API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020041nc_rpc_act_generic(const struct lyd_node *data, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010042{
Michal Vasko90e8e692016-07-13 12:27:57 +020043 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010044
Michal Vasko90e8e692016-07-13 12:27:57 +020045 if (!data || data->next || (data->prev != data)) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020046 ERRARG("data");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010047 return NULL;
48 }
49
Michal Vasko7bcb48e2016-01-15 10:28:54 +010050 rpc = malloc(sizeof *rpc);
51 if (!rpc) {
52 ERRMEM;
53 return NULL;
54 }
55
Michal Vasko90e8e692016-07-13 12:27:57 +020056 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010057 rpc->has_data = 1;
58 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
59 rpc->content.data = lyd_dup(data, 1);
60 } else {
61 rpc->content.data = (struct lyd_node *)data;
62 }
63 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
64
65 return (struct nc_rpc *)rpc;
66}
67
68API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020069nc_rpc_act_generic_xml(const char *xml_str, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010070{
Michal Vasko90e8e692016-07-13 12:27:57 +020071 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010072
Michal Vasko7f1c78b2016-01-19 09:52:14 +010073 if (!xml_str) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020074 ERRARG("xml_str");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010075 return NULL;
76 }
77
Michal Vasko7bcb48e2016-01-15 10:28:54 +010078 rpc = malloc(sizeof *rpc);
79 if (!rpc) {
80 ERRMEM;
81 return NULL;
82 }
83
Michal Vasko90e8e692016-07-13 12:27:57 +020084 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010085 rpc->has_data = 0;
86 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
87 rpc->content.xml_str = strdup(xml_str);
88 } else {
89 rpc->content.xml_str = (char *)xml_str;
90 }
91 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
92
93 return (struct nc_rpc *)rpc;
94}
95
96API struct nc_rpc *
97nc_rpc_getconfig(NC_DATASTORE source, const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
98{
99 struct nc_rpc_getconfig *rpc;
100
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100101 if (!source) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200102 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100103 return NULL;
104 }
105
Michal Vaskof3c647b2016-03-08 12:17:33 +0100106 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko7793bc62016-09-16 11:58:41 +0200107 ERR("Filter is neither an XML subtree nor an XPath expression (invalid first char '%c').", filter[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100108 return NULL;
109 }
110
111 rpc = malloc(sizeof *rpc);
112 if (!rpc) {
113 ERRMEM;
114 return NULL;
115 }
116
117 rpc->type = NC_RPC_GETCONFIG;
118 rpc->source = source;
119 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
120 rpc->filter = strdup(filter);
121 } else {
122 rpc->filter = (char *)filter;
123 }
124 rpc->wd_mode = wd_mode;
125 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
126
127 return (struct nc_rpc *)rpc;
128}
129
130API struct nc_rpc *
131nc_rpc_edit(NC_DATASTORE target, NC_RPC_EDIT_DFLTOP default_op, NC_RPC_EDIT_TESTOPT test_opt,
132 NC_RPC_EDIT_ERROPT error_opt, const char *edit_content, NC_PARAMTYPE paramtype)
133{
134 struct nc_rpc_edit *rpc;
135
Michal Vasko45e53ae2016-04-07 11:46:03 +0200136 if (!target) {
137 ERRARG("target");
138 return NULL;
139 } else if (!edit_content) {
140 ERRARG("edit_content");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100141 return NULL;
142 }
143
Michal Vasko7793bc62016-09-16 11:58:41 +0200144 if (edit_content[0] && (edit_content[0] != '<') && !isalpha(edit_content[0])) {
145 ERR("<edit-config> content is neither a URL nor an XML config (invalid first char '%c').", edit_content[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100146 return NULL;
147 }
148
149 rpc = malloc(sizeof *rpc);
150 if (!rpc) {
151 ERRMEM;
152 return NULL;
153 }
154
155 rpc->type = NC_RPC_EDIT;
156 rpc->target = target;
157 rpc->default_op = default_op;
158 rpc->test_opt = test_opt;
159 rpc->error_opt = error_opt;
160 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
161 rpc->edit_cont = strdup(edit_content);
162 } else {
163 rpc->edit_cont = (char *)edit_content;
164 }
165 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
166
167 return (struct nc_rpc *)rpc;
168}
169
170API struct nc_rpc *
171nc_rpc_copy(NC_DATASTORE target, const char *url_trg, NC_DATASTORE source, const char *url_or_config_src,
172 NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
173{
174 struct nc_rpc_copy *rpc;
175
Michal Vasko45e53ae2016-04-07 11:46:03 +0200176 if (!target) {
177 ERRARG("target");
178 return NULL;
179 } else if (!source) {
180 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100181 return NULL;
182 }
183
Michal Vasko7793bc62016-09-16 11:58:41 +0200184 if (url_or_config_src && url_or_config_src[0] && (url_or_config_src[0] != '<') && !isalpha(url_or_config_src[0])) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200185 ERR("<copy-config> source is neither a URL nor an XML config (invalid first char '%c').", url_or_config_src[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100186 return NULL;
187 }
188
189 rpc = malloc(sizeof *rpc);
190 if (!rpc) {
191 ERRMEM;
192 return NULL;
193 }
194
195 rpc->type = NC_RPC_COPY;
196 rpc->target = target;
197 if (url_trg && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
198 rpc->url_trg = strdup(url_trg);
199 } else {
200 rpc->url_trg = (char *)url_trg;
201 }
202 rpc->source = source;
203 if (url_or_config_src && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
204 rpc->url_config_src = strdup(url_or_config_src);
205 } else {
206 rpc->url_config_src = (char *)url_or_config_src;
207 }
208 rpc->wd_mode = wd_mode;
209 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
210
211 return (struct nc_rpc *)rpc;
212}
213
214API struct nc_rpc *
215nc_rpc_delete(NC_DATASTORE target, const char *url, NC_PARAMTYPE paramtype)
216{
217 struct nc_rpc_delete *rpc;
218
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100219 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200220 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100221 return NULL;
222 }
223
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100224 rpc = malloc(sizeof *rpc);
225 if (!rpc) {
226 ERRMEM;
227 return NULL;
228 }
229
230 rpc->type = NC_RPC_DELETE;
231 rpc->target = target;
232 if (url && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
233 rpc->url = strdup(url);
234 } else {
235 rpc->url = (char *)url;
236 }
237 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
238
239 return (struct nc_rpc *)rpc;
240}
241
242API struct nc_rpc *
243nc_rpc_lock(NC_DATASTORE target)
244{
245 struct nc_rpc_lock *rpc;
246
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100247 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200248 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100249 return NULL;
250 }
251
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100252 rpc = malloc(sizeof *rpc);
253 if (!rpc) {
254 ERRMEM;
255 return NULL;
256 }
257
258 rpc->type = NC_RPC_LOCK;
259 rpc->target = target;
260
261 return (struct nc_rpc *)rpc;
262}
263
264API struct nc_rpc *
265nc_rpc_unlock(NC_DATASTORE target)
266{
267 struct nc_rpc_lock *rpc;
268
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100269 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200270 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100271 return NULL;
272 }
273
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100274 rpc = malloc(sizeof *rpc);
275 if (!rpc) {
276 ERRMEM;
277 return NULL;
278 }
279
280 rpc->type = NC_RPC_UNLOCK;
281 rpc->target = target;
282
283 return (struct nc_rpc *)rpc;
284}
285
286API struct nc_rpc *
287nc_rpc_get(const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
288{
289 struct nc_rpc_get *rpc;
290
Michal Vaskof3c647b2016-03-08 12:17:33 +0100291 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko7793bc62016-09-16 11:58:41 +0200292 ERR("Filter is neither an XML subtree nor an XPath expression (invalid first char '%c').", filter[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100293 return NULL;
294 }
295
296 rpc = malloc(sizeof *rpc);
297 if (!rpc) {
298 ERRMEM;
299 return NULL;
300 }
301
302 rpc->type = NC_RPC_GET;
303 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
304 rpc->filter = strdup(filter);
305 } else {
306 rpc->filter = (char *)filter;
307 }
308 rpc->wd_mode = wd_mode;
309 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
310
311 return (struct nc_rpc *)rpc;
312}
313
314API struct nc_rpc *
315nc_rpc_kill(uint32_t session_id)
316{
317 struct nc_rpc_kill *rpc;
318
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100319 if (!session_id) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200320 ERRARG("session_id");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100321 return NULL;
322 }
323
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100324 rpc = malloc(sizeof *rpc);
325 if (!rpc) {
326 ERRMEM;
327 return NULL;
328 }
329
330 rpc->type = NC_RPC_KILL;
331 rpc->sid = session_id;
332
333 return (struct nc_rpc *)rpc;
334}
335
336API struct nc_rpc *
337nc_rpc_commit(int confirmed, uint32_t confirm_timeout, const char *persist, const char *persist_id,
338 NC_PARAMTYPE paramtype)
339{
340 struct nc_rpc_commit *rpc;
341
342 rpc = malloc(sizeof *rpc);
343 if (!rpc) {
344 ERRMEM;
345 return NULL;
346 }
347
348 rpc->type = NC_RPC_COMMIT;
349 rpc->confirmed = confirmed;
350 rpc->confirm_timeout = confirm_timeout;
351 if (persist && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
352 rpc->persist = strdup(persist);
353 } else {
354 rpc->persist = (char *)persist;
355 }
356 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
357 rpc->persist_id = strdup(persist_id);
358 } else {
359 rpc->persist_id = (char *)persist_id;
360 }
361 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
362
363 return (struct nc_rpc *)rpc;
364}
365
366API struct nc_rpc *
367nc_rpc_discard(void)
368{
369 struct nc_rpc *rpc;
370
371 rpc = malloc(sizeof *rpc);
372 if (!rpc) {
373 ERRMEM;
374 return NULL;
375 }
376
377 rpc->type = NC_RPC_DISCARD;
378
379 return rpc;
380}
381
382API struct nc_rpc *
383nc_rpc_cancel(const char *persist_id, NC_PARAMTYPE paramtype)
384{
385 struct nc_rpc_cancel *rpc;
386
387 rpc = malloc(sizeof *rpc);
388 if (!rpc) {
389 ERRMEM;
390 return NULL;
391 }
392
393 rpc->type = NC_RPC_CANCEL;
394 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
395 rpc->persist_id = strdup(persist_id);
396 } else {
397 rpc->persist_id = (char *)persist_id;
398 }
399 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
400
401 return (struct nc_rpc *)rpc;
402}
403
404API struct nc_rpc *
405nc_rpc_validate(NC_DATASTORE source, const char *url_or_config, NC_PARAMTYPE paramtype)
406{
407 struct nc_rpc_validate *rpc;
408
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100409 if (!source) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200410 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100411 return NULL;
412 }
413
Michal Vasko7793bc62016-09-16 11:58:41 +0200414 if (url_or_config && url_or_config[0] && (url_or_config[0] != '<') && !isalpha(url_or_config[0])) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200415 ERR("<validate> source is neither a URL nor an XML config (invalid first char '%c').", url_or_config[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100416 return NULL;
417 }
418
419 rpc = malloc(sizeof *rpc);
420 if (!rpc) {
421 ERRMEM;
422 return NULL;
423 }
424
425 rpc->type = NC_RPC_VALIDATE;
426 rpc->source = source;
427 if (url_or_config && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
428 rpc->url_config_src = strdup(url_or_config);
429 } else {
430 rpc->url_config_src = (char *)url_or_config;
431 }
432 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
433
434 return (struct nc_rpc *)rpc;
435}
436
437API struct nc_rpc *
438nc_rpc_getschema(const char *identifier, const char *version, const char *format, NC_PARAMTYPE paramtype)
439{
440 struct nc_rpc_getschema *rpc;
441
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100442 if (!identifier) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200443 ERRARG("identifier");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100444 return NULL;
445 }
446
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100447 rpc = malloc(sizeof *rpc);
448 if (!rpc) {
449 ERRMEM;
450 return NULL;
451 }
452
453 rpc->type = NC_RPC_GETSCHEMA;
454 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
455 rpc->identifier = strdup(identifier);
456 } else {
457 rpc->identifier = (char *)identifier;
458 }
459 if (version && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
460 rpc->version = strdup(version);
461 } else {
462 rpc->version = (char *)version;
463 }
464 if (format && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
465 rpc->format = strdup(format);
466 } else {
467 rpc->format = (char *)format;
468 }
469 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
470
471 return (struct nc_rpc *)rpc;
472}
473
474API struct nc_rpc *
475nc_rpc_subscribe(const char *stream_name, const char *filter, const char *start_time, const char *stop_time,
476 NC_PARAMTYPE paramtype)
477{
478 struct nc_rpc_subscribe *rpc;
479
Michal Vaskof3c647b2016-03-08 12:17:33 +0100480 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko7793bc62016-09-16 11:58:41 +0200481 ERR("Filter is neither an XML subtree nor an XPath expression (invalid first char '%c').", filter[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100482 return NULL;
483 }
484
485 rpc = malloc(sizeof *rpc);
486 if (!rpc) {
487 ERRMEM;
488 return NULL;
489 }
490
491 rpc->type = NC_RPC_SUBSCRIBE;
492 if (stream_name && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
493 rpc->stream = strdup(stream_name);
494 } else {
495 rpc->stream = (char *)stream_name;
496 }
497 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
498 rpc->filter = strdup(filter);
499 } else {
500 rpc->filter = (char *)filter;
501 }
502 if (start_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
503 rpc->start = strdup(start_time);
504 } else {
505 rpc->start = (char *)start_time;
506 }
507 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
508 rpc->stop = strdup(stop_time);
509 } else {
510 rpc->stop = (char *)stop_time;
511 }
512 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
513
514 return (struct nc_rpc *)rpc;
515}
516
517API void
518nc_rpc_free(struct nc_rpc *rpc)
519{
Michal Vasko90e8e692016-07-13 12:27:57 +0200520 struct nc_rpc_act_generic *rpc_generic;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100521 struct nc_rpc_getconfig *rpc_getconfig;
522 struct nc_rpc_edit *rpc_edit;
523 struct nc_rpc_copy *rpc_copy;
524 struct nc_rpc_delete *rpc_delete;
525 struct nc_rpc_get *rpc_get;
526 struct nc_rpc_commit *rpc_commit;
527 struct nc_rpc_cancel *rpc_cancel;
528 struct nc_rpc_validate *rpc_validate;
529 struct nc_rpc_getschema *rpc_getschema;
530 struct nc_rpc_subscribe *rpc_subscribe;
531
532 if (!rpc) {
533 return;
534 }
535
536 switch (rpc->type) {
Michal Vasko90e8e692016-07-13 12:27:57 +0200537 case NC_RPC_ACT_GENERIC:
538 rpc_generic = (struct nc_rpc_act_generic *)rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100539 if (rpc_generic->free) {
540 if (rpc_generic->has_data) {
541 lyd_free(rpc_generic->content.data);
542 } else {
543 free(rpc_generic->content.xml_str);
544 }
545 }
546 break;
547 case NC_RPC_GETCONFIG:
548 rpc_getconfig = (struct nc_rpc_getconfig *)rpc;
549 if (rpc_getconfig->free) {
550 free(rpc_getconfig->filter);
551 }
552 break;
553 case NC_RPC_EDIT:
554 rpc_edit = (struct nc_rpc_edit *)rpc;
555 if (rpc_edit->free) {
556 free(rpc_edit->edit_cont);
557 }
558 break;
559 case NC_RPC_COPY:
560 rpc_copy = (struct nc_rpc_copy *)rpc;
561 if (rpc_copy->free) {
562 free(rpc_copy->url_config_src);
David Sedlák35419a32018-10-07 23:23:33 +0200563 free(rpc_copy->url_trg);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100564 }
565 break;
566 case NC_RPC_DELETE:
567 rpc_delete = (struct nc_rpc_delete *)rpc;
568 if (rpc_delete->free) {
569 free(rpc_delete->url);
570 }
571 break;
572 case NC_RPC_GET:
573 rpc_get = (struct nc_rpc_get *)rpc;
574 if (rpc_get->free) {
575 free(rpc_get->filter);
576 }
577 break;
578 case NC_RPC_COMMIT:
579 rpc_commit = (struct nc_rpc_commit *)rpc;
580 if (rpc_commit->free) {
581 free(rpc_commit->persist);
582 free(rpc_commit->persist_id);
583 }
584 break;
585 case NC_RPC_CANCEL:
586 rpc_cancel = (struct nc_rpc_cancel *)rpc;
587 if (rpc_cancel->free) {
588 free(rpc_cancel->persist_id);
589 }
590 break;
591 case NC_RPC_VALIDATE:
592 rpc_validate = (struct nc_rpc_validate *)rpc;
593 if (rpc_validate->free) {
594 free(rpc_validate->url_config_src);
595 }
596 break;
597 case NC_RPC_GETSCHEMA:
598 rpc_getschema = (struct nc_rpc_getschema *)rpc;
599 if (rpc_getschema->free) {
600 free(rpc_getschema->identifier);
601 free(rpc_getschema->version);
602 free(rpc_getschema->format);
603 }
604 break;
605 case NC_RPC_SUBSCRIBE:
606 rpc_subscribe = (struct nc_rpc_subscribe *)rpc;
607 if (rpc_subscribe->free) {
608 free(rpc_subscribe->stream);
609 free(rpc_subscribe->filter);
610 free(rpc_subscribe->start);
611 free(rpc_subscribe->stop);
612 }
613 break;
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100614 default:
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100615 /* nothing special needed */
616 break;
617 }
618
619 free(rpc);
620}
621
622API void
Radek Krejci36d2ee42017-10-13 13:55:59 +0200623nc_client_err_clean(struct nc_err *err, struct ly_ctx *ctx)
624{
625 int i;
626
627 assert(ctx);
628
629 if (!err) {
630 return;
631 }
632
633 lydict_remove(ctx, err->type);
634 lydict_remove(ctx, err->tag);
635 lydict_remove(ctx, err->severity);
636 lydict_remove(ctx, err->apptag);
637 lydict_remove(ctx, err->path);
638 lydict_remove(ctx, err->message);
639 lydict_remove(ctx, err->message_lang);
640 lydict_remove(ctx, err->sid);
641 for (i = 0; i < err->attr_count; ++i) {
642 lydict_remove(ctx, err->attr[i]);
643 }
644 free(err->attr);
645 for (i = 0; i < err->elem_count; ++i) {
646 lydict_remove(ctx, err->elem[i]);
647 }
648 free(err->elem);
649 for (i = 0; i < err->ns_count; ++i) {
650 lydict_remove(ctx, err->ns[i]);
651 }
652 free(err->ns);
653 for (i = 0; i < err->other_count; ++i) {
654 lyxml_free(ctx, err->other[i]);
655 }
656 free(err->other);
657}
658
659API void
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100660nc_reply_free(struct nc_reply *reply)
661{
Michal Vasko1a38c862016-01-15 15:50:07 +0100662 struct nc_client_reply_error *error;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100663 struct nc_reply_data *data;
Radek Krejci36d2ee42017-10-13 13:55:59 +0200664 uint32_t i;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100665
666 if (!reply) {
667 return;
668 }
669
670 switch (reply->type) {
671 case NC_RPL_DATA:
672 data = (struct nc_reply_data *)reply;
673 lyd_free_withsiblings(data->data);
674 break;
675
676 case NC_RPL_OK:
677 /* nothing to free */
678 break;
679
680 case NC_RPL_ERROR:
Michal Vasko1a38c862016-01-15 15:50:07 +0100681 error = (struct nc_client_reply_error *)reply;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100682 for (i = 0; i < error->count; ++i) {
Radek Krejci36d2ee42017-10-13 13:55:59 +0200683 nc_client_err_clean(&error->err[i], error->ctx);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100684 }
685 free(error->err);
686 break;
687
688 case NC_RPL_NOTIF:
689 nc_notif_free((struct nc_notif *)reply);
Michal Vasko11d142a2016-01-19 15:58:24 +0100690 return;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100691 }
692
693 free(reply);
694}
Michal Vasko495c9462016-01-15 11:27:43 +0100695
696API void
697nc_notif_free(struct nc_notif *notif)
698{
699 if (!notif) {
700 return;
701 }
702
703 lydict_remove(notif->tree->schema->module->ctx, notif->datetime);
704 lyd_free(notif->tree);
705 free(notif);
706}