blob: 0ef4b7cffeb07fb31cf53165000edb1cc51daa62 [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
15#include <ctype.h>
16#include <stdlib.h>
17#include <string.h>
18#include <stdarg.h>
19
20#include <libyang/libyang.h>
21
22#include "libnetconf.h"
Michal Vasko7bcb48e2016-01-15 10:28:54 +010023
24const char *rpcedit_dfltop2str[] = {NULL, "merge", "replace", "none"};
25const char *rpcedit_testopt2str[] = {NULL, "test-then-set", "set", "test-only"};
26const char *rpcedit_erropt2str[] = {NULL, "stop-on-error", "continue-on-error", "rollback-on-error"};
27
28API NC_RPC_TYPE
29nc_rpc_get_type(const struct nc_rpc *rpc)
30{
Michal Vasko7f1c78b2016-01-19 09:52:14 +010031 if (!rpc) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020032 ERRARG("rpc");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010033 return 0;
34 }
35
Michal Vasko7bcb48e2016-01-15 10:28:54 +010036 return rpc->type;
37}
38
39API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020040nc_rpc_act_generic(const struct lyd_node *data, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010041{
Michal Vasko90e8e692016-07-13 12:27:57 +020042 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010043
Michal Vasko90e8e692016-07-13 12:27:57 +020044 if (!data || data->next || (data->prev != data)) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020045 ERRARG("data");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010046 return NULL;
47 }
48
Michal Vasko7bcb48e2016-01-15 10:28:54 +010049 rpc = malloc(sizeof *rpc);
50 if (!rpc) {
51 ERRMEM;
52 return NULL;
53 }
54
Michal Vasko90e8e692016-07-13 12:27:57 +020055 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010056 rpc->has_data = 1;
57 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
58 rpc->content.data = lyd_dup(data, 1);
59 } else {
60 rpc->content.data = (struct lyd_node *)data;
61 }
62 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
63
64 return (struct nc_rpc *)rpc;
65}
66
67API struct nc_rpc *
Michal Vasko90e8e692016-07-13 12:27:57 +020068nc_rpc_act_generic_xml(const char *xml_str, NC_PARAMTYPE paramtype)
Michal Vasko7bcb48e2016-01-15 10:28:54 +010069{
Michal Vasko90e8e692016-07-13 12:27:57 +020070 struct nc_rpc_act_generic *rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010071
Michal Vasko7f1c78b2016-01-19 09:52:14 +010072 if (!xml_str) {
Michal Vasko45e53ae2016-04-07 11:46:03 +020073 ERRARG("xml_str");
Michal Vasko7f1c78b2016-01-19 09:52:14 +010074 return NULL;
75 }
76
Michal Vasko7bcb48e2016-01-15 10:28:54 +010077 rpc = malloc(sizeof *rpc);
78 if (!rpc) {
79 ERRMEM;
80 return NULL;
81 }
82
Michal Vasko90e8e692016-07-13 12:27:57 +020083 rpc->type = NC_RPC_ACT_GENERIC;
Michal Vasko7bcb48e2016-01-15 10:28:54 +010084 rpc->has_data = 0;
85 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
86 rpc->content.xml_str = strdup(xml_str);
87 } else {
88 rpc->content.xml_str = (char *)xml_str;
89 }
90 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
91
92 return (struct nc_rpc *)rpc;
93}
94
95API struct nc_rpc *
96nc_rpc_getconfig(NC_DATASTORE source, const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
97{
98 struct nc_rpc_getconfig *rpc;
99
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100100 if (!source) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200101 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100102 return NULL;
103 }
104
Michal Vaskof3c647b2016-03-08 12:17:33 +0100105 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko7793bc62016-09-16 11:58:41 +0200106 ERR("Filter is neither an XML subtree nor an XPath expression (invalid first char '%c').", filter[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100107 return NULL;
108 }
109
110 rpc = malloc(sizeof *rpc);
111 if (!rpc) {
112 ERRMEM;
113 return NULL;
114 }
115
116 rpc->type = NC_RPC_GETCONFIG;
117 rpc->source = source;
118 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
119 rpc->filter = strdup(filter);
120 } else {
121 rpc->filter = (char *)filter;
122 }
123 rpc->wd_mode = wd_mode;
124 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
125
126 return (struct nc_rpc *)rpc;
127}
128
129API struct nc_rpc *
130nc_rpc_edit(NC_DATASTORE target, NC_RPC_EDIT_DFLTOP default_op, NC_RPC_EDIT_TESTOPT test_opt,
131 NC_RPC_EDIT_ERROPT error_opt, const char *edit_content, NC_PARAMTYPE paramtype)
132{
133 struct nc_rpc_edit *rpc;
134
Michal Vasko45e53ae2016-04-07 11:46:03 +0200135 if (!target) {
136 ERRARG("target");
137 return NULL;
138 } else if (!edit_content) {
139 ERRARG("edit_content");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100140 return NULL;
141 }
142
Michal Vasko7793bc62016-09-16 11:58:41 +0200143 if (edit_content[0] && (edit_content[0] != '<') && !isalpha(edit_content[0])) {
144 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 +0100145 return NULL;
146 }
147
148 rpc = malloc(sizeof *rpc);
149 if (!rpc) {
150 ERRMEM;
151 return NULL;
152 }
153
154 rpc->type = NC_RPC_EDIT;
155 rpc->target = target;
156 rpc->default_op = default_op;
157 rpc->test_opt = test_opt;
158 rpc->error_opt = error_opt;
159 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
160 rpc->edit_cont = strdup(edit_content);
161 } else {
162 rpc->edit_cont = (char *)edit_content;
163 }
164 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
165
166 return (struct nc_rpc *)rpc;
167}
168
169API struct nc_rpc *
170nc_rpc_copy(NC_DATASTORE target, const char *url_trg, NC_DATASTORE source, const char *url_or_config_src,
171 NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
172{
173 struct nc_rpc_copy *rpc;
174
Michal Vasko45e53ae2016-04-07 11:46:03 +0200175 if (!target) {
176 ERRARG("target");
177 return NULL;
178 } else if (!source) {
179 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100180 return NULL;
181 }
182
Michal Vasko7793bc62016-09-16 11:58:41 +0200183 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 +0200184 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 +0100185 return NULL;
186 }
187
188 rpc = malloc(sizeof *rpc);
189 if (!rpc) {
190 ERRMEM;
191 return NULL;
192 }
193
194 rpc->type = NC_RPC_COPY;
195 rpc->target = target;
196 if (url_trg && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
197 rpc->url_trg = strdup(url_trg);
198 } else {
199 rpc->url_trg = (char *)url_trg;
200 }
201 rpc->source = source;
202 if (url_or_config_src && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
203 rpc->url_config_src = strdup(url_or_config_src);
204 } else {
205 rpc->url_config_src = (char *)url_or_config_src;
206 }
207 rpc->wd_mode = wd_mode;
208 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
209
210 return (struct nc_rpc *)rpc;
211}
212
213API struct nc_rpc *
214nc_rpc_delete(NC_DATASTORE target, const char *url, NC_PARAMTYPE paramtype)
215{
216 struct nc_rpc_delete *rpc;
217
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100218 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200219 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100220 return NULL;
221 }
222
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100223 rpc = malloc(sizeof *rpc);
224 if (!rpc) {
225 ERRMEM;
226 return NULL;
227 }
228
229 rpc->type = NC_RPC_DELETE;
230 rpc->target = target;
231 if (url && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
232 rpc->url = strdup(url);
233 } else {
234 rpc->url = (char *)url;
235 }
236 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
237
238 return (struct nc_rpc *)rpc;
239}
240
241API struct nc_rpc *
242nc_rpc_lock(NC_DATASTORE target)
243{
244 struct nc_rpc_lock *rpc;
245
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100246 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200247 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100248 return NULL;
249 }
250
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100251 rpc = malloc(sizeof *rpc);
252 if (!rpc) {
253 ERRMEM;
254 return NULL;
255 }
256
257 rpc->type = NC_RPC_LOCK;
258 rpc->target = target;
259
260 return (struct nc_rpc *)rpc;
261}
262
263API struct nc_rpc *
264nc_rpc_unlock(NC_DATASTORE target)
265{
266 struct nc_rpc_lock *rpc;
267
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100268 if (!target) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200269 ERRARG("target");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100270 return NULL;
271 }
272
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100273 rpc = malloc(sizeof *rpc);
274 if (!rpc) {
275 ERRMEM;
276 return NULL;
277 }
278
279 rpc->type = NC_RPC_UNLOCK;
280 rpc->target = target;
281
282 return (struct nc_rpc *)rpc;
283}
284
285API struct nc_rpc *
286nc_rpc_get(const char *filter, NC_WD_MODE wd_mode, NC_PARAMTYPE paramtype)
287{
288 struct nc_rpc_get *rpc;
289
Michal Vaskof3c647b2016-03-08 12:17:33 +0100290 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko7793bc62016-09-16 11:58:41 +0200291 ERR("Filter is neither an XML subtree nor an XPath expression (invalid first char '%c').", filter[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100292 return NULL;
293 }
294
295 rpc = malloc(sizeof *rpc);
296 if (!rpc) {
297 ERRMEM;
298 return NULL;
299 }
300
301 rpc->type = NC_RPC_GET;
302 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
303 rpc->filter = strdup(filter);
304 } else {
305 rpc->filter = (char *)filter;
306 }
307 rpc->wd_mode = wd_mode;
308 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
309
310 return (struct nc_rpc *)rpc;
311}
312
313API struct nc_rpc *
314nc_rpc_kill(uint32_t session_id)
315{
316 struct nc_rpc_kill *rpc;
317
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100318 if (!session_id) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200319 ERRARG("session_id");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100320 return NULL;
321 }
322
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100323 rpc = malloc(sizeof *rpc);
324 if (!rpc) {
325 ERRMEM;
326 return NULL;
327 }
328
329 rpc->type = NC_RPC_KILL;
330 rpc->sid = session_id;
331
332 return (struct nc_rpc *)rpc;
333}
334
335API struct nc_rpc *
336nc_rpc_commit(int confirmed, uint32_t confirm_timeout, const char *persist, const char *persist_id,
337 NC_PARAMTYPE paramtype)
338{
339 struct nc_rpc_commit *rpc;
340
341 rpc = malloc(sizeof *rpc);
342 if (!rpc) {
343 ERRMEM;
344 return NULL;
345 }
346
347 rpc->type = NC_RPC_COMMIT;
348 rpc->confirmed = confirmed;
349 rpc->confirm_timeout = confirm_timeout;
350 if (persist && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
351 rpc->persist = strdup(persist);
352 } else {
353 rpc->persist = (char *)persist;
354 }
355 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
356 rpc->persist_id = strdup(persist_id);
357 } else {
358 rpc->persist_id = (char *)persist_id;
359 }
360 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
361
362 return (struct nc_rpc *)rpc;
363}
364
365API struct nc_rpc *
366nc_rpc_discard(void)
367{
368 struct nc_rpc *rpc;
369
370 rpc = malloc(sizeof *rpc);
371 if (!rpc) {
372 ERRMEM;
373 return NULL;
374 }
375
376 rpc->type = NC_RPC_DISCARD;
377
378 return rpc;
379}
380
381API struct nc_rpc *
382nc_rpc_cancel(const char *persist_id, NC_PARAMTYPE paramtype)
383{
384 struct nc_rpc_cancel *rpc;
385
386 rpc = malloc(sizeof *rpc);
387 if (!rpc) {
388 ERRMEM;
389 return NULL;
390 }
391
392 rpc->type = NC_RPC_CANCEL;
393 if (persist_id && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
394 rpc->persist_id = strdup(persist_id);
395 } else {
396 rpc->persist_id = (char *)persist_id;
397 }
398 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
399
400 return (struct nc_rpc *)rpc;
401}
402
403API struct nc_rpc *
404nc_rpc_validate(NC_DATASTORE source, const char *url_or_config, NC_PARAMTYPE paramtype)
405{
406 struct nc_rpc_validate *rpc;
407
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100408 if (!source) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200409 ERRARG("source");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100410 return NULL;
411 }
412
Michal Vasko7793bc62016-09-16 11:58:41 +0200413 if (url_or_config && url_or_config[0] && (url_or_config[0] != '<') && !isalpha(url_or_config[0])) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200414 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 +0100415 return NULL;
416 }
417
418 rpc = malloc(sizeof *rpc);
419 if (!rpc) {
420 ERRMEM;
421 return NULL;
422 }
423
424 rpc->type = NC_RPC_VALIDATE;
425 rpc->source = source;
426 if (url_or_config && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
427 rpc->url_config_src = strdup(url_or_config);
428 } else {
429 rpc->url_config_src = (char *)url_or_config;
430 }
431 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
432
433 return (struct nc_rpc *)rpc;
434}
435
436API struct nc_rpc *
437nc_rpc_getschema(const char *identifier, const char *version, const char *format, NC_PARAMTYPE paramtype)
438{
439 struct nc_rpc_getschema *rpc;
440
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100441 if (!identifier) {
Michal Vasko45e53ae2016-04-07 11:46:03 +0200442 ERRARG("identifier");
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100443 return NULL;
444 }
445
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100446 rpc = malloc(sizeof *rpc);
447 if (!rpc) {
448 ERRMEM;
449 return NULL;
450 }
451
452 rpc->type = NC_RPC_GETSCHEMA;
453 if (paramtype == NC_PARAMTYPE_DUP_AND_FREE) {
454 rpc->identifier = strdup(identifier);
455 } else {
456 rpc->identifier = (char *)identifier;
457 }
458 if (version && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
459 rpc->version = strdup(version);
460 } else {
461 rpc->version = (char *)version;
462 }
463 if (format && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
464 rpc->format = strdup(format);
465 } else {
466 rpc->format = (char *)format;
467 }
468 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
469
470 return (struct nc_rpc *)rpc;
471}
472
473API struct nc_rpc *
474nc_rpc_subscribe(const char *stream_name, const char *filter, const char *start_time, const char *stop_time,
475 NC_PARAMTYPE paramtype)
476{
477 struct nc_rpc_subscribe *rpc;
478
Michal Vaskof3c647b2016-03-08 12:17:33 +0100479 if (filter && filter[0] && (filter[0] != '<') && (filter[0] != '/') && !isalpha(filter[0])) {
Michal Vasko7793bc62016-09-16 11:58:41 +0200480 ERR("Filter is neither an XML subtree nor an XPath expression (invalid first char '%c').", filter[0]);
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100481 return NULL;
482 }
483
484 rpc = malloc(sizeof *rpc);
485 if (!rpc) {
486 ERRMEM;
487 return NULL;
488 }
489
490 rpc->type = NC_RPC_SUBSCRIBE;
491 if (stream_name && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
492 rpc->stream = strdup(stream_name);
493 } else {
494 rpc->stream = (char *)stream_name;
495 }
496 if (filter && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
497 rpc->filter = strdup(filter);
498 } else {
499 rpc->filter = (char *)filter;
500 }
501 if (start_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
502 rpc->start = strdup(start_time);
503 } else {
504 rpc->start = (char *)start_time;
505 }
506 if (stop_time && (paramtype == NC_PARAMTYPE_DUP_AND_FREE)) {
507 rpc->stop = strdup(stop_time);
508 } else {
509 rpc->stop = (char *)stop_time;
510 }
511 rpc->free = (paramtype == NC_PARAMTYPE_CONST ? 0 : 1);
512
513 return (struct nc_rpc *)rpc;
514}
515
516API void
517nc_rpc_free(struct nc_rpc *rpc)
518{
Michal Vasko90e8e692016-07-13 12:27:57 +0200519 struct nc_rpc_act_generic *rpc_generic;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100520 struct nc_rpc_getconfig *rpc_getconfig;
521 struct nc_rpc_edit *rpc_edit;
522 struct nc_rpc_copy *rpc_copy;
523 struct nc_rpc_delete *rpc_delete;
524 struct nc_rpc_get *rpc_get;
525 struct nc_rpc_commit *rpc_commit;
526 struct nc_rpc_cancel *rpc_cancel;
527 struct nc_rpc_validate *rpc_validate;
528 struct nc_rpc_getschema *rpc_getschema;
529 struct nc_rpc_subscribe *rpc_subscribe;
530
531 if (!rpc) {
532 return;
533 }
534
535 switch (rpc->type) {
Michal Vasko90e8e692016-07-13 12:27:57 +0200536 case NC_RPC_ACT_GENERIC:
537 rpc_generic = (struct nc_rpc_act_generic *)rpc;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100538 if (rpc_generic->free) {
539 if (rpc_generic->has_data) {
540 lyd_free(rpc_generic->content.data);
541 } else {
542 free(rpc_generic->content.xml_str);
543 }
544 }
545 break;
546 case NC_RPC_GETCONFIG:
547 rpc_getconfig = (struct nc_rpc_getconfig *)rpc;
548 if (rpc_getconfig->free) {
549 free(rpc_getconfig->filter);
550 }
551 break;
552 case NC_RPC_EDIT:
553 rpc_edit = (struct nc_rpc_edit *)rpc;
554 if (rpc_edit->free) {
555 free(rpc_edit->edit_cont);
556 }
557 break;
558 case NC_RPC_COPY:
559 rpc_copy = (struct nc_rpc_copy *)rpc;
560 if (rpc_copy->free) {
561 free(rpc_copy->url_config_src);
562 }
563 break;
564 case NC_RPC_DELETE:
565 rpc_delete = (struct nc_rpc_delete *)rpc;
566 if (rpc_delete->free) {
567 free(rpc_delete->url);
568 }
569 break;
570 case NC_RPC_GET:
571 rpc_get = (struct nc_rpc_get *)rpc;
572 if (rpc_get->free) {
573 free(rpc_get->filter);
574 }
575 break;
576 case NC_RPC_COMMIT:
577 rpc_commit = (struct nc_rpc_commit *)rpc;
578 if (rpc_commit->free) {
579 free(rpc_commit->persist);
580 free(rpc_commit->persist_id);
581 }
582 break;
583 case NC_RPC_CANCEL:
584 rpc_cancel = (struct nc_rpc_cancel *)rpc;
585 if (rpc_cancel->free) {
586 free(rpc_cancel->persist_id);
587 }
588 break;
589 case NC_RPC_VALIDATE:
590 rpc_validate = (struct nc_rpc_validate *)rpc;
591 if (rpc_validate->free) {
592 free(rpc_validate->url_config_src);
593 }
594 break;
595 case NC_RPC_GETSCHEMA:
596 rpc_getschema = (struct nc_rpc_getschema *)rpc;
597 if (rpc_getschema->free) {
598 free(rpc_getschema->identifier);
599 free(rpc_getschema->version);
600 free(rpc_getschema->format);
601 }
602 break;
603 case NC_RPC_SUBSCRIBE:
604 rpc_subscribe = (struct nc_rpc_subscribe *)rpc;
605 if (rpc_subscribe->free) {
606 free(rpc_subscribe->stream);
607 free(rpc_subscribe->filter);
608 free(rpc_subscribe->start);
609 free(rpc_subscribe->stop);
610 }
611 break;
Michal Vasko7f1c78b2016-01-19 09:52:14 +0100612 default:
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100613 /* nothing special needed */
614 break;
615 }
616
617 free(rpc);
618}
619
620API void
621nc_reply_free(struct nc_reply *reply)
622{
Michal Vasko1a38c862016-01-15 15:50:07 +0100623 struct nc_client_reply_error *error;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100624 struct nc_reply_data *data;
625 uint32_t i, j;
626
627 if (!reply) {
628 return;
629 }
630
631 switch (reply->type) {
632 case NC_RPL_DATA:
633 data = (struct nc_reply_data *)reply;
634 lyd_free_withsiblings(data->data);
635 break;
636
637 case NC_RPL_OK:
638 /* nothing to free */
639 break;
640
641 case NC_RPL_ERROR:
Michal Vasko1a38c862016-01-15 15:50:07 +0100642 error = (struct nc_client_reply_error *)reply;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100643 for (i = 0; i < error->count; ++i) {
644 lydict_remove(error->ctx, error->err[i].type);
645 lydict_remove(error->ctx, error->err[i].tag);
646 lydict_remove(error->ctx, error->err[i].severity);
647 lydict_remove(error->ctx, error->err[i].apptag);
648 lydict_remove(error->ctx, error->err[i].path);
649 lydict_remove(error->ctx, error->err[i].message);
650 lydict_remove(error->ctx, error->err[i].message_lang);
651 lydict_remove(error->ctx, error->err[i].sid);
652 for (j = 0; j < error->err[i].attr_count; ++j) {
653 lydict_remove(error->ctx, error->err[i].attr[j]);
654 }
655 free(error->err[i].attr);
656 for (j = 0; j < error->err[i].elem_count; ++j) {
657 lydict_remove(error->ctx, error->err[i].elem[j]);
658 }
659 free(error->err[i].elem);
660 for (j = 0; j < error->err[i].ns_count; ++j) {
661 lydict_remove(error->ctx, error->err[i].ns[j]);
662 }
663 free(error->err[i].ns);
664 for (j = 0; j < error->err[i].other_count; ++j) {
665 lyxml_free(error->ctx, error->err[i].other[j]);
666 }
667 free(error->err[i].other);
668 }
669 free(error->err);
670 break;
671
672 case NC_RPL_NOTIF:
673 nc_notif_free((struct nc_notif *)reply);
Michal Vasko11d142a2016-01-19 15:58:24 +0100674 return;
Michal Vasko7bcb48e2016-01-15 10:28:54 +0100675 }
676
677 free(reply);
678}
Michal Vasko495c9462016-01-15 11:27:43 +0100679
680API void
681nc_notif_free(struct nc_notif *notif)
682{
683 if (!notif) {
684 return;
685 }
686
687 lydict_remove(notif->tree->schema->module->ctx, notif->datetime);
688 lyd_free(notif->tree);
689 free(notif);
690}