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_time.h>
21 #include <sml/sml_shared.h>
22 #include <sml/sml_number.h>
23 #include <stdio.h>
24 
sml_time_init()25 sml_time *sml_time_init() {
26 	sml_time *t = (sml_time *) malloc(sizeof(sml_time));
27 	*t = ( sml_time ) {
28 		.tag = NULL,
29 		.data.sec_index = NULL
30 	};
31 	return t;
32 }
33 
sml_time_parse(sml_buffer * buf)34 sml_time *sml_time_parse(sml_buffer *buf) {
35 	if (sml_buf_optional_is_skipped(buf)) {
36 		return 0;
37 	}
38 
39 	sml_time *tme = sml_time_init();
40 
41 	if (sml_buf_get_next_type(buf) != SML_TYPE_LIST) {
42 		buf->error = 1;
43 		goto error;
44 	}
45 
46 	if (sml_buf_get_next_length(buf) != 2) {
47 		buf->error = 1;
48 		goto error;
49 	}
50 
51 	tme->tag = sml_u8_parse(buf);
52 	if (sml_buf_has_errors(buf)) goto error;
53 
54 	int type = sml_buf_get_next_type(buf);
55 	switch (type) {
56 	case SML_TYPE_UNSIGNED:
57 		tme->data.timestamp = sml_u32_parse(buf);
58 		if (sml_buf_has_errors(buf)) goto error;
59 		break;
60 	case SML_TYPE_LIST:
61 		// Some meters (e.g. FROETEC Multiflex ZG22) giving not one uint32
62 		// as timestamp, but a list of 3 values.
63 		// Ignoring these values, so that parsing does not fail.
64 		sml_buf_get_next_length(buf); // should we check the length here?
65 		u32 *t1 = sml_u32_parse(buf);
66 		if (sml_buf_has_errors(buf)) goto error;
67 		i16 *t2 = sml_i16_parse(buf);
68 		if (sml_buf_has_errors(buf)) goto error;
69 		i16 *t3 = sml_i16_parse(buf);
70 		if (sml_buf_has_errors(buf)) goto error;
71 		fprintf(stderr,
72 			"libsml: error: sml_time as list[3]: ignoring value[0]=%u value[1]=%d value[2]=%d\n",
73 			*t1, *t2, *t3);
74 		break;
75 	default:
76 		goto error;
77 	}
78 
79 	return tme;
80 
81 error:
82 	sml_time_free(tme);
83 	return 0;
84 }
85 
sml_time_write(sml_time * t,sml_buffer * buf)86 void sml_time_write(sml_time *t, sml_buffer *buf) {
87 	if (t == 0) {
88 		sml_buf_optional_write(buf);
89 		return;
90 	}
91 
92 	sml_buf_set_type_and_length(buf, SML_TYPE_LIST, 2);
93 	sml_u8_write(t->tag, buf);
94 	sml_u32_write(t->data.timestamp, buf);
95 }
96 
sml_time_free(sml_time * tme)97 void sml_time_free(sml_time *tme) {
98     if (tme) {
99 		sml_number_free(tme->tag);
100 		sml_number_free(tme->data.timestamp);
101         free(tme);
102     }
103 }
104 
105