1 // Copyright 2011 Juri Glass, Mathias Runge, Nadim El Sayed
2 // DAI-Labor, TU-Berlin
3 //
4 // This file is part of libSML.
5 //
6 // libSML is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // libSML is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with libSML. If not, see <http://www.gnu.org/licenses/>.
18
19
20 #include <sml/sml_tree.h>
21 #include <sml/sml_value.h>
22 #include <stdio.h>
23
24 // sml_tree_path;
25
sml_tree_path_init()26 sml_tree_path *sml_tree_path_init() {
27 sml_tree_path *tree_path = (sml_tree_path *) malloc(sizeof(sml_tree_path));
28 *tree_path = ( sml_tree_path ) {
29 .path_entries_len = 0,
30 .path_entries = NULL
31 };
32
33 return tree_path;
34 }
35
sml_tree_path_parse(sml_buffer * buf)36 sml_tree_path *sml_tree_path_parse(sml_buffer *buf) {
37 if (sml_buf_optional_is_skipped(buf)) {
38 return 0;
39 }
40
41 sml_tree_path *tree_path = sml_tree_path_init();
42
43 if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
44 buf->error = 1;
45 return 0;
46 }
47
48 octet_string *s;
49 int elems;
50 for (elems = sml_buf_get_next_length(buf); elems > 0; elems--) {
51 s = sml_octet_string_parse(buf);
52 if (sml_buf_has_errors(buf)) goto error;
53 if (s) {
54 sml_tree_path_add_path_entry(tree_path, s);
55 }
56 }
57
58 return tree_path;
59
60 error:
61 buf->error = 1;
62 sml_tree_path_free(tree_path);
63 return 0;
64 }
65
sml_tree_path_add_path_entry(sml_tree_path * tree_path,octet_string * entry)66 void sml_tree_path_add_path_entry(sml_tree_path *tree_path, octet_string *entry) {
67 tree_path->path_entries_len++;
68 tree_path->path_entries = (octet_string **) realloc(tree_path->path_entries,
69 sizeof(octet_string *) * tree_path->path_entries_len);
70
71 tree_path->path_entries[tree_path->path_entries_len - 1] = entry;
72 }
73
sml_tree_path_write(sml_tree_path * tree_path,sml_buffer * buf)74 void sml_tree_path_write(sml_tree_path *tree_path, sml_buffer *buf) {
75 if (tree_path == 0) {
76 sml_buf_optional_write(buf);
77 return;
78 }
79
80 if (tree_path->path_entries && tree_path->path_entries_len > 0) {
81 sml_buf_set_type_and_length(buf, SML_TYPE_LIST, tree_path->path_entries_len);
82
83 int i;
84 for (i = 0; i < tree_path->path_entries_len; i++) {
85 sml_octet_string_write(tree_path->path_entries[i], buf);
86 }
87 }
88 }
89
sml_tree_path_free(sml_tree_path * tree_path)90 void sml_tree_path_free(sml_tree_path *tree_path) {
91 if (tree_path) {
92 if (tree_path->path_entries && tree_path->path_entries_len > 0) {
93 int i;
94 for (i = 0; i < tree_path->path_entries_len; i++) {
95 sml_octet_string_free(tree_path->path_entries[i]);
96 }
97
98 free(tree_path->path_entries);
99 }
100
101 free(tree_path);
102 }
103 }
104
105
106 // sml_tree;
107
sml_tree_init()108 sml_tree *sml_tree_init() {
109 sml_tree *tree = (sml_tree *) malloc(sizeof(sml_tree));
110 *tree = ( sml_tree ) {
111 .parameter_name = NULL,
112 .parameter_value = NULL,
113 .child_list = NULL,
114 .child_list_len = 0
115 };
116
117 return tree;
118 }
119
sml_tree_parse(sml_buffer * buf)120 sml_tree *sml_tree_parse(sml_buffer *buf) {
121 if (sml_buf_optional_is_skipped(buf)) {
122 return 0;
123 }
124
125 sml_tree *tree = sml_tree_init();
126
127 if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
128 buf->error = 1;
129 goto error;
130 }
131
132 if (sml_buf_get_next_length(buf) != 3) {
133 buf->error = 1;
134 goto error;
135 }
136
137 tree->parameter_name = sml_octet_string_parse(buf);
138 if (sml_buf_has_errors(buf)) goto error;
139
140 tree->parameter_value = sml_proc_par_value_parse(buf);
141 if (sml_buf_has_errors(buf)) goto error;
142
143 if (!sml_buf_optional_is_skipped(buf)) {
144 if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
145 buf->error = 1;
146 goto error;
147 }
148
149 sml_tree *c;
150 int elems;
151 for (elems = sml_buf_get_next_length(buf); elems > 0; elems--) {
152 c = sml_tree_parse(buf);
153 if (sml_buf_has_errors(buf)) goto error;
154 if (c) {
155 sml_tree_add_tree(tree, c);
156 }
157 }
158 }
159
160 return tree;
161
162 error:
163 sml_tree_free(tree);
164 return 0;
165 }
166
sml_tree_add_tree(sml_tree * base_tree,sml_tree * tree)167 void sml_tree_add_tree(sml_tree *base_tree, sml_tree *tree) {
168 base_tree->child_list_len++;
169 base_tree->child_list = (sml_tree **) realloc(base_tree->child_list,
170 sizeof(sml_tree *) * base_tree->child_list_len);
171 base_tree->child_list[base_tree->child_list_len - 1] = tree;
172 }
173
sml_tree_free(sml_tree * tree)174 void sml_tree_free(sml_tree *tree) {
175 if (tree) {
176 sml_octet_string_free(tree->parameter_name);
177 sml_proc_par_value_free(tree->parameter_value);
178 int i;
179 for (i = 0; i < tree->child_list_len; i++) {
180 sml_tree_free(tree->child_list[i]);
181 }
182
183 free(tree->child_list);
184 free(tree);
185 }
186 }
187
sml_tree_write(sml_tree * tree,sml_buffer * buf)188 void sml_tree_write(sml_tree *tree, sml_buffer *buf) {
189 if (tree == 0) {
190 sml_buf_optional_write(buf);
191 return;
192 }
193
194 sml_buf_set_type_and_length(buf, SML_TYPE_LIST, 3);
195
196 sml_octet_string_write(tree->parameter_name, buf);
197 sml_proc_par_value_write(tree->parameter_value, buf);
198
199 if (tree->child_list && tree->child_list_len > 0) {
200 sml_buf_set_type_and_length(buf, SML_TYPE_LIST, tree->child_list_len);
201
202 int i;
203 for (i = 0; i < tree->child_list_len; i++) {
204 sml_tree_write(tree->child_list[i], buf);
205 }
206 }
207 else {
208 sml_buf_optional_write(buf);
209 }
210 }
211
212
213 // sml_proc_par_value;
214
sml_proc_par_value_init()215 sml_proc_par_value *sml_proc_par_value_init() {
216 sml_proc_par_value *value = (sml_proc_par_value *) malloc(sizeof(sml_proc_par_value));
217 *value = ( sml_proc_par_value ) {
218 .tag = NULL,
219 .data.value = NULL
220 };
221 return value;
222 }
223
sml_proc_par_value_parse(sml_buffer * buf)224 sml_proc_par_value *sml_proc_par_value_parse(sml_buffer *buf) {
225 if (sml_buf_optional_is_skipped(buf)) {
226 return 0;
227 }
228
229 sml_proc_par_value *ppv = sml_proc_par_value_init();
230
231 if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
232 buf->error = 1;
233 goto error;
234 }
235
236 if (sml_buf_get_next_length(buf) != 2) {
237 buf->error = 1;
238 goto error;
239 }
240
241 ppv->tag = sml_u8_parse(buf);
242 if (sml_buf_has_errors(buf)) goto error;
243
244 switch (*(ppv->tag)) {
245 case SML_PROC_PAR_VALUE_TAG_VALUE:
246 ppv->data.value = sml_value_parse(buf);
247 break;
248 case SML_PROC_PAR_VALUE_TAG_PERIOD_ENTRY:
249 ppv->data.period_entry = sml_period_entry_parse(buf);
250 break;
251 case SML_PROC_PAR_VALUE_TAG_TUPEL_ENTRY:
252 ppv->data.tupel_entry = sml_tupel_entry_parse(buf);
253 break;
254 case SML_PROC_PAR_VALUE_TAG_TIME:
255 ppv->data.time = sml_time_parse(buf);
256 break;
257 default:
258 buf->error = 1;
259 goto error;
260 }
261
262 return ppv;
263
264 error:
265 sml_proc_par_value_free(ppv);
266 return 0;
267 }
268
sml_proc_par_value_write(sml_proc_par_value * value,sml_buffer * buf)269 void sml_proc_par_value_write(sml_proc_par_value *value, sml_buffer *buf) {
270 if (value == 0) {
271 sml_buf_optional_write(buf);
272 return;
273 }
274
275 sml_buf_set_type_and_length(buf, SML_TYPE_LIST, 2);
276 sml_u8_write(value->tag, buf);
277
278 switch (*(value->tag)) {
279 case SML_PROC_PAR_VALUE_TAG_VALUE:
280 sml_value_write(value->data.value, buf);
281 break;
282 case SML_PROC_PAR_VALUE_TAG_PERIOD_ENTRY:
283 sml_period_entry_write(value->data.period_entry, buf);
284 break;
285 case SML_PROC_PAR_VALUE_TAG_TUPEL_ENTRY:
286 sml_tupel_entry_write(value->data.tupel_entry, buf);
287 break;
288 case SML_PROC_PAR_VALUE_TAG_TIME:
289 sml_time_write(value->data.time, buf);
290 break;
291 default:
292 fprintf(stderr,"libsml: error: unknown tag in %s\n", __FUNCTION__);
293 }
294 }
295
sml_proc_par_value_free(sml_proc_par_value * ppv)296 void sml_proc_par_value_free(sml_proc_par_value *ppv) {
297 if (ppv) {
298 if (ppv->tag) {
299 switch (*(ppv->tag)) {
300 case SML_PROC_PAR_VALUE_TAG_VALUE:
301 sml_value_free(ppv->data.value);
302 break;
303 case SML_PROC_PAR_VALUE_TAG_PERIOD_ENTRY:
304 sml_period_entry_free(ppv->data.period_entry);
305 break;
306 case SML_PROC_PAR_VALUE_TAG_TUPEL_ENTRY:
307 sml_tupel_entry_free(ppv->data.tupel_entry);
308 break;
309 case SML_PROC_PAR_VALUE_TAG_TIME:
310 sml_time_free(ppv->data.time);
311 break;
312 default:
313 if (ppv->data.value) {
314 free(ppv->data.value);
315 }
316 }
317 sml_number_free(ppv->tag);
318 }
319 else {
320 // Without the tag, there might be a memory leak.
321 if (ppv->data.value) {
322 free(ppv->data.value);
323 }
324 }
325
326 free(ppv);
327 }
328 }
329
330
331 // sml_tuple_entry;
332
sml_tupel_entry_init()333 sml_tupel_entry *sml_tupel_entry_init() {
334 sml_tupel_entry *tupel = (sml_tupel_entry *) malloc(sizeof(sml_tupel_entry));
335 *tupel = ( sml_tupel_entry ) {
336 .server_id = NULL,
337 .sec_index = NULL,
338 .status = NULL,
339 .unit_pA = NULL,
340 .scaler_pA = NULL,
341 .value_pA = NULL,
342 .unit_R1 = NULL,
343 .scaler_R1 = NULL,
344 .value_R1 = NULL,
345 .unit_R4 = NULL,
346 .scaler_R4 = NULL,
347 .value_R4 = NULL,
348 .signature_pA_R1_R4 = NULL,
349 .unit_mA = NULL,
350 .scaler_mA = NULL,
351 .value_mA = NULL,
352 .unit_R2 = NULL,
353 .scaler_R2 = NULL,
354 .value_R2 = NULL,
355 .unit_R3 = NULL,
356 .scaler_R3 = NULL,
357 .value_R3 = NULL,
358 .signature_mA_R2_R3 = NULL
359 };
360
361 return tupel;
362 }
363
sml_tupel_entry_parse(sml_buffer * buf)364 sml_tupel_entry *sml_tupel_entry_parse(sml_buffer *buf) {
365 if (sml_buf_optional_is_skipped(buf)) {
366 return 0;
367 }
368
369 sml_tupel_entry *tupel = sml_tupel_entry_init();
370
371 if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
372 buf->error = 1;
373 goto error;
374 }
375
376 if (sml_buf_get_next_length(buf) != 23) {
377 buf->error = 1;
378 goto error;
379 }
380
381 tupel->server_id = sml_octet_string_parse(buf);
382 if (sml_buf_has_errors(buf)) goto error;
383 tupel->sec_index = sml_time_parse(buf);
384 if (sml_buf_has_errors(buf)) goto error;
385 tupel->status = sml_u64_parse(buf);
386 if (sml_buf_has_errors(buf)) goto error;
387
388 tupel->unit_pA = sml_unit_parse(buf);
389 if (sml_buf_has_errors(buf)) goto error;
390 tupel->scaler_pA = sml_i8_parse(buf);
391 if (sml_buf_has_errors(buf)) goto error;
392 tupel->value_pA = sml_i64_parse(buf);
393 if (sml_buf_has_errors(buf)) goto error;
394
395 tupel->unit_R1 = sml_unit_parse(buf);
396 if (sml_buf_has_errors(buf)) goto error;
397 tupel->scaler_R1 = sml_i8_parse(buf);
398 if (sml_buf_has_errors(buf)) goto error;
399 tupel->value_R1 = sml_i64_parse(buf);
400 if (sml_buf_has_errors(buf)) goto error;
401
402 tupel->unit_R4 = sml_unit_parse(buf);
403 if (sml_buf_has_errors(buf)) goto error;
404 tupel->scaler_R4 = sml_i8_parse(buf);
405 if (sml_buf_has_errors(buf)) goto error;
406 tupel->value_R4 = sml_i64_parse(buf);
407 if (sml_buf_has_errors(buf)) goto error;
408
409 tupel->signature_pA_R1_R4 = sml_octet_string_parse(buf);
410 if (sml_buf_has_errors(buf)) goto error;
411
412 tupel->unit_mA = sml_unit_parse(buf);
413 if (sml_buf_has_errors(buf)) goto error;
414 tupel->scaler_mA = sml_i8_parse(buf);
415 if (sml_buf_has_errors(buf)) goto error;
416 tupel->value_mA = sml_i64_parse(buf);
417 if (sml_buf_has_errors(buf)) goto error;
418
419 tupel->unit_R2 = sml_unit_parse(buf);
420 if (sml_buf_has_errors(buf)) goto error;
421 tupel->scaler_R2 = sml_i8_parse(buf);
422 if (sml_buf_has_errors(buf)) goto error;
423 tupel->value_R2 = sml_i64_parse(buf);
424 if (sml_buf_has_errors(buf)) goto error;
425
426 tupel->unit_R3 = sml_unit_parse(buf);
427 if (sml_buf_has_errors(buf)) goto error;
428 tupel->scaler_R3 = sml_i8_parse(buf);
429 if (sml_buf_has_errors(buf)) goto error;
430 tupel->value_R3 = sml_i64_parse(buf);
431 if (sml_buf_has_errors(buf)) goto error;
432
433 tupel->signature_mA_R2_R3 = sml_octet_string_parse(buf);
434 if (sml_buf_has_errors(buf)) goto error;
435
436 return tupel;
437
438 error:
439 sml_tupel_entry_free(tupel);
440 return 0;
441 }
442
sml_tupel_entry_write(sml_tupel_entry * tupel,sml_buffer * buf)443 void sml_tupel_entry_write(sml_tupel_entry *tupel, sml_buffer *buf) {
444 if (tupel == 0) {
445 sml_buf_optional_write(buf);
446 return;
447 }
448
449 sml_buf_set_type_and_length(buf, SML_TYPE_LIST, 23);
450
451 sml_octet_string_write(tupel->server_id, buf);
452 sml_time_write(tupel->sec_index, buf);
453 sml_u64_write(tupel->status, buf);
454
455 sml_unit_write(tupel->unit_pA, buf);
456 sml_i8_write(tupel->scaler_pA, buf);
457 sml_i64_write(tupel->value_pA, buf);
458
459 sml_unit_write(tupel->unit_R1, buf);
460 sml_i8_write(tupel->scaler_R1, buf);
461 sml_i64_write(tupel->value_R1, buf);
462
463 sml_unit_write(tupel->unit_R4, buf);
464 sml_i8_write(tupel->scaler_R4, buf);
465 sml_i64_write(tupel->value_R4, buf);
466
467 sml_octet_string_write(tupel->signature_pA_R1_R4, buf);
468
469 sml_unit_write(tupel->unit_mA, buf);
470 sml_i8_write(tupel->scaler_mA, buf);
471 sml_i64_write(tupel->value_mA, buf);
472
473 sml_unit_write(tupel->unit_R2, buf);
474 sml_i8_write(tupel->scaler_R2, buf);
475 sml_i64_write(tupel->value_R2, buf);
476
477 sml_unit_write(tupel->unit_R3, buf);
478 sml_i8_write(tupel->scaler_R3, buf);
479 sml_i64_write(tupel->value_R3, buf);
480
481 sml_octet_string_write(tupel->signature_mA_R2_R3, buf);
482 }
483
sml_tupel_entry_free(sml_tupel_entry * tupel)484 void sml_tupel_entry_free(sml_tupel_entry *tupel) {
485 if (tupel) {
486 sml_octet_string_free(tupel->server_id);
487 sml_time_free(tupel->sec_index);
488 sml_number_free(tupel->status);
489
490 sml_unit_free(tupel->unit_pA);
491 sml_number_free(tupel->scaler_pA);
492 sml_number_free(tupel->value_pA);
493
494 sml_unit_free(tupel->unit_R1);
495 sml_number_free(tupel->scaler_R1);
496 sml_number_free(tupel->value_R1);
497
498 sml_unit_free(tupel->unit_R4);
499 sml_number_free(tupel->scaler_R4);
500 sml_number_free(tupel->value_R4);
501
502 sml_octet_string_free(tupel->signature_pA_R1_R4);
503
504 sml_unit_free(tupel->unit_mA);
505 sml_number_free(tupel->scaler_mA);
506 sml_number_free(tupel->value_mA);
507
508 sml_unit_free(tupel->unit_R2);
509 sml_number_free(tupel->scaler_R2);
510 sml_number_free(tupel->value_R2);
511
512 sml_unit_free(tupel->unit_R3);
513 sml_number_free(tupel->scaler_R3);
514 sml_number_free(tupel->value_R3);
515
516 sml_octet_string_free(tupel->signature_mA_R2_R3);
517
518 free(tupel);
519 }
520 }
521
522
523
524 // sml_period_entry;
525
sml_period_entry_init()526 sml_period_entry *sml_period_entry_init() {
527 sml_period_entry *period = (sml_period_entry *) malloc(sizeof(sml_period_entry));
528 *period = ( sml_period_entry ) {
529 .obj_name = NULL,
530 .unit = NULL,
531 .scaler = NULL,
532 .value = NULL,
533 .value_signature = NULL
534 };
535
536 return period;
537 }
538
sml_period_entry_parse_(sml_buffer * buf)539 static void * sml_period_entry_parse_(sml_buffer *buf) {
540 if (sml_buf_optional_is_skipped(buf)) {
541 return 0;
542 }
543
544 sml_period_entry *period = sml_period_entry_init();
545
546 if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
547 buf->error = 1;
548 goto error;
549 }
550
551 if (sml_buf_get_next_length(buf) != 5) {
552 buf->error = 1;
553 goto error;
554 }
555
556 period->obj_name = sml_octet_string_parse(buf);
557 if (sml_buf_has_errors(buf)) goto error;
558
559 period->unit = sml_unit_parse(buf);
560 if (sml_buf_has_errors(buf)) goto error;
561
562 period->scaler = sml_i8_parse(buf);
563 if (sml_buf_has_errors(buf)) goto error;
564
565 period->value = sml_value_parse(buf);
566 if (sml_buf_has_errors(buf)) goto error;
567
568 period->value_signature = sml_octet_string_parse(buf);
569 if (sml_buf_has_errors(buf)) goto error;
570
571 return period;
572
573 error:
574 sml_period_entry_free(period);
575 return 0;
576 }
577
sml_period_entry_parse(sml_buffer * buf)578 sml_period_entry * sml_period_entry_parse( sml_buffer * buf ) {
579 return sml_period_entry_parse_( buf );
580 }
581
sml_period_entry_write(sml_period_entry * period,sml_buffer * buf)582 void sml_period_entry_write(sml_period_entry *period, sml_buffer *buf) {
583 if (period == 0) {
584 sml_buf_optional_write(buf);
585 return;
586 }
587
588 sml_buf_set_type_and_length(buf, SML_TYPE_LIST, 5);
589
590 sml_octet_string_write(period->obj_name, buf);
591 sml_unit_write(period->unit, buf);
592 sml_i8_write(period->scaler, buf);
593 sml_value_write(period->value, buf);
594 sml_octet_string_write(period->value_signature, buf);
595 }
596
sml_period_entry_free_(void * p)597 static void sml_period_entry_free_( void * p ) {
598 sml_period_entry * period = p;
599
600 if (period) {
601 sml_octet_string_free(period->obj_name);
602 sml_unit_free(period->unit);
603 sml_number_free(period->scaler);
604 sml_value_free(period->value);
605 sml_octet_string_free(period->value_signature);
606
607 free(period);
608 }
609 }
610
sml_period_entry_free(sml_period_entry * period)611 void sml_period_entry_free( sml_period_entry * period ) {
612 sml_period_entry_free_( period );
613 }
614