blob: c571c3bd499c483a5b8dc0024f254b7cf803f13d [file] [log] [blame]
Harald Weltefbd02fa2016-04-25 15:19:35 +02001#include <osmocom/gsm/tlv.h>
2
3static void check_tlv_parse(uint8_t **data, size_t *data_len,
4 uint8_t exp_tag, size_t exp_len, const uint8_t *exp_val)
5{
6 uint8_t *value;
7 size_t value_len;
8 uint8_t tag;
9 int rc;
10 uint8_t *saved_data = *data;
11 size_t saved_data_len = *data_len;
12
13 rc = osmo_match_shift_tlv(data, data_len, exp_tag ^ 1, NULL, NULL);
14 OSMO_ASSERT(rc == 0);
15
16 rc = osmo_match_shift_tlv(data, data_len, exp_tag, &value, &value_len);
17 OSMO_ASSERT(rc == (int)value_len + 2);
18 OSMO_ASSERT(value_len == exp_len);
19 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
20
21 /* restore data/data_len */
22 *data = saved_data;
23 *data_len = saved_data_len;
24
25 rc = osmo_shift_tlv(data, data_len, &tag, &value, &value_len);
26 OSMO_ASSERT(rc == (int)value_len + 2);
27 OSMO_ASSERT(tag == exp_tag);
28 OSMO_ASSERT(value_len == exp_len);
29 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
30}
31
32static void check_tv_fixed_match(uint8_t **data, size_t *data_len,
33 uint8_t tag, size_t len, const uint8_t *exp_val)
34{
35 uint8_t *value;
36 int rc;
37
38 rc = osmo_match_shift_tv_fixed(data, data_len, tag ^ 1, len, NULL);
39 OSMO_ASSERT(rc == 0);
40
41 rc = osmo_match_shift_tv_fixed(data, data_len, tag, len, &value);
42 OSMO_ASSERT(rc == (int)len + 1);
43 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
44}
45
46static void check_v_fixed_shift(uint8_t **data, size_t *data_len,
47 size_t len, const uint8_t *exp_val)
48{
49 uint8_t *value;
50 int rc;
51
52 rc = osmo_shift_v_fixed(data, data_len, len, &value);
53 OSMO_ASSERT(rc == (int)len);
54 OSMO_ASSERT(memcmp(value, exp_val, len) == 0);
55}
56
57static void check_lv_shift(uint8_t **data, size_t *data_len,
58 size_t exp_len, const uint8_t *exp_val)
59{
60 uint8_t *value;
61 size_t value_len;
62 int rc;
63
64 rc = osmo_shift_lv(data, data_len, &value, &value_len);
65 OSMO_ASSERT(rc == (int)value_len + 1);
66 OSMO_ASSERT(value_len == exp_len);
67 OSMO_ASSERT(memcmp(value, exp_val, exp_len) == 0);
68}
69
70static void check_tlv_match_data_len(size_t data_len, uint8_t tag, size_t len,
71 const uint8_t *test_data)
72{
73 uint8_t buf[300] = {0};
74
75 uint8_t *unchanged_ptr = buf - 1;
76 size_t unchanged_len = 0xdead;
77 size_t tmp_data_len = data_len;
78 uint8_t *value = unchanged_ptr;
79 size_t value_len = unchanged_len;
80 uint8_t *data = buf;
81
82 OSMO_ASSERT(data_len <= sizeof(buf));
83
84 tlv_put(data, tag, len, test_data);
85 if (data_len < len + 2) {
86 OSMO_ASSERT(-1 == osmo_match_shift_tlv(&data, &tmp_data_len,
87 tag, &value, &value_len));
88 OSMO_ASSERT(tmp_data_len == 0);
89 OSMO_ASSERT(data == buf + data_len);
90 OSMO_ASSERT(value == unchanged_ptr);
91 OSMO_ASSERT(value_len == unchanged_len);
92 } else {
93 OSMO_ASSERT(0 <= osmo_match_shift_tlv(&data, &tmp_data_len,
94 tag, &value, &value_len));
95 OSMO_ASSERT(value != unchanged_ptr);
96 OSMO_ASSERT(value_len != unchanged_len);
97 }
98}
99
100static void check_tv_fixed_match_data_len(size_t data_len,
101 uint8_t tag, size_t len,
102 const uint8_t *test_data)
103{
104 uint8_t buf[300] = {0};
105
106 uint8_t *unchanged_ptr = buf - 1;
107 size_t tmp_data_len = data_len;
108 uint8_t *value = unchanged_ptr;
109 uint8_t *data = buf;
110
111 OSMO_ASSERT(data_len <= sizeof(buf));
112
113 tv_fixed_put(data, tag, len, test_data);
114
115 if (data_len < len + 1) {
116 OSMO_ASSERT(-1 == osmo_match_shift_tv_fixed(&data, &tmp_data_len,
117 tag, len, &value));
118 OSMO_ASSERT(tmp_data_len == 0);
119 OSMO_ASSERT(data == buf + data_len);
120 OSMO_ASSERT(value == unchanged_ptr);
121 } else {
122 OSMO_ASSERT(0 <= osmo_match_shift_tv_fixed(&data, &tmp_data_len,
123 tag, len, &value));
124 OSMO_ASSERT(value != unchanged_ptr);
125 }
126}
127
128static void check_v_fixed_shift_data_len(size_t data_len,
129 size_t len, const uint8_t *test_data)
130{
131 uint8_t buf[300] = {0};
132
133 uint8_t *unchanged_ptr = buf - 1;
134 size_t tmp_data_len = data_len;
135 uint8_t *value = unchanged_ptr;
136 uint8_t *data = buf;
137
138 OSMO_ASSERT(data_len <= sizeof(buf));
139
140 memcpy(data, test_data, len);
141
142 if (data_len < len) {
143 OSMO_ASSERT(-1 == osmo_shift_v_fixed(&data, &tmp_data_len,
144 len, &value));
145 OSMO_ASSERT(tmp_data_len == 0);
146 OSMO_ASSERT(data == buf + data_len);
147 OSMO_ASSERT(value == unchanged_ptr);
148 } else {
149 OSMO_ASSERT(0 <= osmo_shift_v_fixed(&data, &tmp_data_len,
150 len, &value));
151 OSMO_ASSERT(value != unchanged_ptr);
152 }
153}
154
155static void check_lv_shift_data_len(size_t data_len,
156 size_t len, const uint8_t *test_data)
157{
158 uint8_t buf[300] = {0};
159
160 uint8_t *unchanged_ptr = buf - 1;
161 size_t unchanged_len = 0xdead;
162 size_t tmp_data_len = data_len;
163 uint8_t *value = unchanged_ptr;
164 size_t value_len = unchanged_len;
165 uint8_t *data = buf;
166
167 lv_put(data, len, test_data);
168 if (data_len < len + 1) {
169 OSMO_ASSERT(-1 == osmo_shift_lv(&data, &tmp_data_len,
170 &value, &value_len));
171 OSMO_ASSERT(tmp_data_len == 0);
172 OSMO_ASSERT(data == buf + data_len);
173 OSMO_ASSERT(value == unchanged_ptr);
174 OSMO_ASSERT(value_len == unchanged_len);
175 } else {
176 OSMO_ASSERT(0 <= osmo_shift_lv(&data, &tmp_data_len,
177 &value, &value_len));
178 OSMO_ASSERT(value != unchanged_ptr);
179 OSMO_ASSERT(value_len != unchanged_len);
180 }
181}
182
183static void test_tlv_shift_functions()
184{
185 uint8_t test_data[1024];
186 uint8_t buf[1024];
187 uint8_t *data_end;
188 unsigned i, len;
189 uint8_t *data;
190 size_t data_len;
191 const uint8_t tag = 0x1a;
192
193 printf("Test shift functions\n");
194
195 for (i = 0; i < ARRAY_SIZE(test_data); i++)
196 test_data[i] = (uint8_t)i;
197
198 for (len = 0; len < 256; len++) {
199 const unsigned iterations = sizeof(buf) / (len + 2) / 4;
200
201 memset(buf, 0xee, sizeof(buf));
202 data_end = data = buf;
203
204 for (i = 0; i < iterations; i++) {
205 data_end = tlv_put(data_end, tag, len, test_data);
206 data_end = tv_fixed_put(data_end, tag, len, test_data);
207 /* v_fixed_put */
208 memcpy(data_end, test_data, len);
209 data_end += len;
210 data_end = lv_put(data_end, len, test_data);
211 }
212
213 data_len = data_end - data;
214 OSMO_ASSERT(data_len <= sizeof(buf));
215
216 for (i = 0; i < iterations; i++) {
217 check_tlv_parse(&data, &data_len, tag, len, test_data);
218 check_tv_fixed_match(&data, &data_len, tag, len, test_data);
219 check_v_fixed_shift(&data, &data_len, len, test_data);
220 check_lv_shift(&data, &data_len, len, test_data);
221 }
222
223 OSMO_ASSERT(data == data_end);
224
225 /* Test at end of data */
226
227 OSMO_ASSERT(-1 == osmo_match_shift_tlv(&data, &data_len, tag, NULL, NULL));
228 OSMO_ASSERT(-1 == osmo_match_shift_tv_fixed(&data, &data_len, tag, len, NULL));
229 OSMO_ASSERT((len ? -1 : 0) == osmo_shift_v_fixed(&data, &data_len, len, NULL));
230 OSMO_ASSERT(-1 == osmo_shift_lv(&data, &data_len, NULL, NULL));
231
232 /* Test invalid data_len */
233 for (data_len = 0; data_len <= len + 2 + 1; data_len += 1) {
234 check_tlv_match_data_len(data_len, tag, len, test_data);
235 check_tv_fixed_match_data_len(data_len, tag, len, test_data);
236 check_v_fixed_shift_data_len(data_len, len, test_data);
237 check_lv_shift_data_len(data_len, len, test_data);
238 }
239 }
240}
241
242int main(int argc, char **argv)
243{
244 //osmo_init_logging(&info);
245
246 test_tlv_shift_functions();
247
248 printf("Done.\n");
249 return EXIT_SUCCESS;
250}