1 /*
2  *  libzvbi -- VPS low level functions unit test
3  *
4  *  Copyright (C) 2006, 2008 Michael H. Schimek
5  *
6  *  This program 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 2 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program 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 this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19  *  MA 02110-1301, USA.
20  */
21 
22 /* $Id: test-vps.cc,v 1.1 2009/03/04 21:48:17 mschimek Exp $ */
23 
24 #undef NDEBUG
25 
26 #ifdef HAVE_CONFIG_H
27 #  include "config.h"
28 #endif
29 
30 #include <limits.h>
31 #include "src/vps.h"
32 #include "test-pdc.h"
33 
34 #define N_ELEMENTS(array) (sizeof (array) / sizeof (*(array)))
35 
36 static const unsigned int
37 valid_cnis [] = {
38 	0x000, 0x001, 0x004, 0x010, 0x040, 0x100,
39 	0x400, 0x5A5, 0xA5A, 0xFFF
40 };
41 
42 static const uint8_t
43 vps_sample [13] = {
44 	0xB1, 0x04, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x00,
45 	/* 1011 0001 0000 0100 1010 0000
46 	                       aa   cccc
47 			       10   fedc */
48 	0xC3, 0x76, 0x3F, 0x41, 0xFF
49 	/* 1100 0011 0111 0110 0011 1111 0100 0001 1111 1111
50 	   ccdd dddm mmmh hhhh mmmm mmcc cccc cccc pppp pppp
51 	   7643 2103 2104 3210 5432 10ba 9854 3210 7654 3210 */
52 };
53 
54 static void
assert_decode_vps_cni(unsigned int * cni,const uint8_t buffer[13])55 assert_decode_vps_cni		(unsigned int *		cni,
56 				 const uint8_t		buffer[13])
57 {
58 	uint8_t buffer2[13];
59 	unsigned int cni2;
60 
61 	memcpy (buffer2, buffer, sizeof (buffer2));
62 	memset_rand (cni, sizeof (*cni));
63 	cni2 = *cni;
64 
65 	assert (TRUE == vbi_decode_vps_cni (cni, buffer));
66 	assert ((unsigned int) *cni <= 0xFFF);
67 	assert (0 == memcmp (buffer, buffer2, sizeof (buffer2)));
68 }
69 
70 static void
assert_encode_vps_cni(uint8_t buffer[13],unsigned int cni,vbi_bool exp_success=TRUE)71 assert_encode_vps_cni		(uint8_t		buffer[13],
72 				 unsigned int		cni,
73 				 vbi_bool		exp_success = TRUE)
74 {
75 	static const uint8_t cni_bits[13] = {
76 		0, 0, 0x0F, 0, 0, 0, 0, 0, 0xC0, 0, 0x03, 0xFF, 0
77 	};
78 	uint8_t buffer2[13];
79 	unsigned int i;
80 
81 	memset_rand (buffer2, sizeof (buffer2));
82 	memcpy (buffer, buffer2, sizeof (buffer2));
83 
84 	assert (exp_success == vbi_encode_vps_cni (buffer, cni));
85 	if (exp_success) {
86 		buffer2[2] |= 0x0F;
87 		for (i = 0; i < sizeof (buffer2); ++i) {
88 			assert (0 == ((buffer[i] ^ buffer2[i])
89 				      & ~cni_bits[i]));
90 		}
91 	} else {
92 		assert (0 == memcmp (buffer, buffer2, sizeof (buffer2)));
93 	}
94 }
95 
96 static void
assert_decode_vps_pdc(test_pid * pid,const uint8_t buffer[13],const test_pid * exp_pid=NULL)97 assert_decode_vps_pdc		(test_pid *		pid,
98 				 const uint8_t		buffer[13],
99 				 const test_pid *	exp_pid = NULL)
100 {
101 	uint8_t buffer2[13];
102 	test_pid pid2;
103 	unsigned int cni;
104 
105 	memcpy (buffer2, buffer, sizeof (buffer2));
106 	pid->randomize ();
107 	pid2 = *pid;
108 
109 	assert (TRUE == vbi_decode_vps_pdc (pid, buffer));
110 	pid->assert_valid_vps ();
111 	assert_decode_vps_cni (&cni, buffer);
112 	assert (cni == pid->cni);
113 	if (NULL != exp_pid) {
114 		assert (exp_pid->cni == pid->cni);
115 		assert (exp_pid->pil == pid->pil);
116 		assert (exp_pid->pcs_audio == pid->pcs_audio);
117 		assert (exp_pid->pty == pid->pty);
118 	}
119 	assert (0 == memcmp (buffer, buffer2, sizeof (buffer2)));
120 }
121 
122 static void
assert_encode_vps_pdc(uint8_t buffer[13],const test_pid * pid,vbi_bool exp_success=TRUE)123 assert_encode_vps_pdc		(uint8_t		buffer[13],
124 				 const test_pid *	pid,
125 				 vbi_bool		exp_success = TRUE)
126 {
127 	static const uint8_t pdc_bits[13] = {
128 		0, 0, 0xFF, 0, 0, 0, 0, 0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF
129 	};
130 	uint8_t buffer2[13];
131 	test_pid pid2;
132 	unsigned int i;
133 
134 	pid2 = *pid;
135 	memset_rand (buffer2, sizeof (buffer2));
136 	memcpy (buffer, buffer2, sizeof (buffer2));
137 
138 	assert (exp_success == vbi_encode_vps_pdc (buffer, pid));
139 	if (exp_success) {
140 		buffer2[2] |= 0x0F;
141 		for (i = 0; i < 13; ++i) {
142 			assert (0 == ((buffer[i] ^ buffer2[i])
143 				      & ~pdc_bits[i]));
144 		}
145 	} else {
146 		assert (0 == memcmp (buffer, buffer2, sizeof (buffer2)));
147 	}
148 
149 	assert (pid2 == *pid);
150 }
151 
152 static void
assert_decode_dvb_pdc_descriptor(test_pid * pid,const uint8_t buffer[5],vbi_bool exp_success=TRUE,const test_pid * exp_pid=NULL)153 assert_decode_dvb_pdc_descriptor
154 				(test_pid *		pid,
155 				 const uint8_t		buffer[5],
156 				 vbi_bool		exp_success = TRUE,
157 				 const test_pid *	exp_pid = NULL)
158 {
159 	uint8_t buffer2[5];
160 	test_pid pid2;
161 
162 	memcpy (buffer2, buffer, sizeof (buffer2));
163 	pid->randomize ();
164 	pid2 = *pid;
165 
166 	assert (exp_success == vbi_decode_dvb_pdc_descriptor (pid, buffer));
167 	if (exp_success) {
168 		pid->assert_valid_dvb ();
169 		if (NULL != exp_pid) {
170 			assert (exp_pid->pil == pid->pil);
171 		}
172 	} else {
173 		assert (pid2 == *pid);
174 	}
175 
176 	assert (0 == memcmp (buffer, buffer2, sizeof (buffer2)));
177 }
178 
179 static void
assert_encode_dvb_pdc_descriptor(uint8_t buffer[5],const test_pid * pid,vbi_bool exp_success=TRUE)180 assert_encode_dvb_pdc_descriptor
181 				(uint8_t		buffer[5],
182 				 const test_pid *	pid,
183 				 vbi_bool		exp_success = TRUE)
184 {
185 	uint8_t buffer2[5];
186 	test_pid pid2;
187 
188 	pid2 = *pid;
189 	memset_rand (buffer2, sizeof (buffer2));
190 	memcpy (buffer, buffer2, sizeof (buffer2));
191 
192 	assert (exp_success == vbi_encode_dvb_pdc_descriptor (buffer, pid));
193 	if (exp_success) {
194 		/* EN 300 468 section 6.1, 6.2. */
195 		assert (0x69 == buffer[0]);
196 		assert (3 == buffer[1]);
197 		/* EN 300 468 section 3.1. */
198 		assert (0xF0 == (buffer[2] & 0xF0));
199 	} else {
200 		assert (0 == memcmp (buffer, buffer2, sizeof (buffer2)));
201 	}
202 
203 	assert (pid2 == *pid);
204 }
205 
206 int
main(void)207 main				(void)
208 {
209 	uint8_t buffer1[13];
210 	test_pid pid1;
211 	test_pid pid2;
212 	unsigned int cni;
213 	unsigned int i;
214 
215 	for (i = 0; i < N_ELEMENTS (valid_cnis); ++i) {
216 		assert_encode_vps_cni (buffer1, valid_cnis[i]);
217 		assert_decode_vps_cni (&cni, buffer1);
218 		assert (cni == valid_cnis[i]);
219 	}
220 
221 	assert_decode_vps_cni (&cni, vps_sample);
222 	assert (0x0DC1 == cni);
223 
224 	/* TR 101 231. */
225 	assert_encode_vps_cni (buffer1, 0xDC3);
226 	buffer1[5 - 3] &= ~(0x80 >> 3);
227 	assert_decode_vps_cni (&cni, buffer1);
228 	assert (0xDC2 == cni); /* ZDF */
229 	buffer1[5 - 3] |= 0x80 >> 3;
230 	assert_decode_vps_cni (&cni, buffer1);
231 	assert (0xDC1 == cni); /* ARD */
232 
233 	assert_encode_vps_cni (buffer1, 0x1000, FALSE);
234 	assert_encode_vps_cni (buffer1, INT_MIN, FALSE);
235 	assert_encode_vps_cni (buffer1, INT_MAX, FALSE);
236 	assert_encode_vps_cni (buffer1, UINT_MAX, FALSE);
237 
238 	for (i = 0; i < 1000; ++i) {
239 		pid1.populate_vps ();
240 		assert_encode_vps_pdc (buffer1, &pid1);
241 
242 		assert_decode_vps_cni (&cni, buffer1);
243 		assert (cni == pid1.cni);
244 
245 		assert_decode_vps_pdc (&pid2, buffer1, &pid1);
246 
247 		memset_rand (buffer1, sizeof (buffer1));
248 		assert_decode_vps_pdc (&pid2, buffer1);
249 
250 		pid1.randomize ();
251 		pid1.pil &= max_pil;
252 		assert_encode_dvb_pdc_descriptor (buffer1, &pid1);
253 
254 		assert_decode_dvb_pdc_descriptor (&pid2, buffer1,
255 						  TRUE, &pid1);
256 
257 		memset_rand (buffer1, sizeof (buffer1));
258 		/* EN 300 468 section 6.1, 6.2. */
259 		buffer1[0] = 0x69;
260 		buffer1[1] = 3;
261 		assert_decode_dvb_pdc_descriptor (&pid2, buffer1);
262 	}
263 
264 	assert_decode_vps_pdc (&pid1, vps_sample);
265 	assert (0xDC1 == pid1.cni);
266 	assert (VBI_PIL (0x0B, 0x01, 0x16, 0x0F) == pid1.pil);
267 	assert (0x02 == pid1.pcs_audio);
268 	assert (0xFF == pid1.pty);
269 
270 	pid1.populate_vps ();
271 	pid1.cni = 0x1000;
272 	assert_encode_vps_pdc (buffer1, &pid1, FALSE);
273 	pid1.cni = UINT_MAX;
274 	assert_encode_vps_pdc (buffer1, &pid1, FALSE);
275 
276 	/* TR 101 231. */
277 	pid1.populate_vps ();
278 	pid1.cni = 0xDC3;
279 	assert_encode_vps_pdc (buffer1, &pid1);
280 	buffer1[5 - 3] &= ~(0x80 >> 3);
281 	assert_decode_vps_pdc (&pid1, buffer1);
282 	assert (0xDC2 == pid1.cni);
283 	buffer1[5 - 3] |= 0x80 >> 3;
284 	assert_decode_vps_pdc (&pid1, buffer1);
285 	assert (0xDC1 == pid1.cni);
286 
287 	pid1.populate_vps ();
288 	pid1.pil = max_pil + 1;
289 	assert_encode_vps_pdc (buffer1, &pid1, FALSE);
290 	pid1.pil = UINT_MAX;
291 	assert_encode_vps_pdc (buffer1, &pid1, FALSE);
292 
293 	pid1.populate_vps ();
294 	pid1.pcs_audio = (vbi_pcs_audio) 4;
295 	assert_encode_vps_pdc (buffer1, &pid1, FALSE);
296 	pid1.pcs_audio = (vbi_pcs_audio) UINT_MAX;
297 	assert_encode_vps_pdc (buffer1, &pid1, FALSE);
298 
299 	pid1.populate_vps ();
300 	pid1.pty = 0x100;
301 	assert_encode_vps_pdc (buffer1, &pid1, FALSE);
302 	pid1.pty = UINT_MAX;
303 	assert_encode_vps_pdc (buffer1, &pid1, FALSE);
304 
305 	/* EN 300 468 section 6.1, 6.2. */
306 	memset_rand (buffer1, sizeof (buffer1));
307 	buffer1[0] = 0x69;
308 	buffer1[1] = 2;
309 	assert_decode_dvb_pdc_descriptor (&pid2, buffer1, FALSE);
310 	buffer1[1] = 4;
311 	assert_decode_dvb_pdc_descriptor (&pid2, buffer1, FALSE);
312 	buffer1[0] = 0x6a;
313 	buffer1[1] = 3;
314 	assert_decode_dvb_pdc_descriptor (&pid2, buffer1, FALSE);
315 
316 	pid1.randomize ();
317 	pid1.pil = max_pil + 1;
318 	assert_encode_dvb_pdc_descriptor (buffer1, &pid1, FALSE);
319 	pid1.pil = UINT_MAX;
320 	assert_encode_dvb_pdc_descriptor (buffer1, &pid1, FALSE);
321 
322 	return 0;
323 }
324 
325 /*
326 Local variables:
327 c-set-style: K&R
328 c-basic-offset: 8
329 End:
330 */
331