• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013 - Mauro Carvalho Chehab <mchehab@kernel.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser General Public License as published by
6  * the Free Software Foundation version 2.1 of the License.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11  * GNU Lesser General Public License for more details.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, write to the Free Software
15  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16  * Or, point your browser to http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
17  *
18  */
19 
20 #include <libdvbv5/desc_extension.h>
21 #include <libdvbv5/desc_t2_delivery.h>
22 #include <libdvbv5/dvb-fe.h>
23 
24 #if __GNUC__ >= 9
25 #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
26 #endif
27 
28 const struct dvb_ext_descriptor dvb_ext_descriptors[] = {
29 	[0 ...255 ] = {
30 		.name  = "Unknown descriptor",
31 		.init  = NULL,
32 		.print = NULL,
33 		.free  = NULL,
34 		.size  = 0,
35 	},
36 	[image_icon_descriptor] = {
37 		.name  = "image_icon_descriptor",
38 		.init  = NULL,
39 		.print = NULL,
40 		.free  = NULL,
41 		.size  = 0,
42 	},
43 	[cpcm_delivery_signalling_descriptor] = {
44 		.name  = "cpcm_delivery_signalling_descriptor",
45 		.init  = NULL,
46 		.print = NULL,
47 		.free  = NULL,
48 		.size  = 0,
49 	},
50 	[CP_descriptor] = {
51 		.name  = "CP_descriptor",
52 		.init  = NULL,
53 		.print = NULL,
54 		.free  = NULL,
55 		.size  = 0,
56 	},
57 	[CP_identifier_descriptor] = {
58 		.name  = "CP_identifier_descriptor",
59 		.init  = NULL,
60 		.print = NULL,
61 		.free  = NULL,
62 		.size  = 0,
63 	},
64 	[T2_delivery_system_descriptor] = {
65 		.name  = "T2_delivery_system_descriptor",
66 		.init  = dvb_desc_t2_delivery_init,
67 		.print = dvb_desc_t2_delivery_print,
68 		.free  = dvb_desc_t2_delivery_free,
69 		.size  = sizeof(struct dvb_desc_t2_delivery),
70 	},
71 	[SH_delivery_system_descriptor] = {
72 		.name  = "SH_delivery_system_descriptor",
73 		.init  = NULL,
74 		.print = NULL,
75 		.free  = NULL,
76 		.size  = 0,
77 	},
78 	[supplementary_audio_descriptor] = {
79 		.name  = "supplementary_audio_descriptor",
80 		.init  = NULL,
81 		.print = NULL,
82 		.free  = NULL,
83 		.size  = 0,
84 	},
85 	[network_change_notify_descriptor] = {
86 		.name  = "network_change_notify_descriptor",
87 		.init  = NULL,
88 		.print = NULL,
89 		.free  = NULL,
90 		.size  = 0,
91 	},
92 	[message_descriptor] = {
93 		.name  = "message_descriptor",
94 		.init  = NULL,
95 		.print = NULL,
96 		.free  = NULL,
97 		.size  = 0,
98 	},
99 	[target_region_descriptor] = {
100 		.name  = "target_region_descriptor",
101 		.init  = NULL,
102 		.print = NULL,
103 		.free  = NULL,
104 		.size  = 0,
105 	},
106 	[target_region_name_descriptor] = {
107 		.name  = "target_region_name_descriptor",
108 		.init  = NULL,
109 		.print = NULL,
110 		.free  = NULL,
111 		.size  = 0,
112 	},
113 	[service_relocated_descriptor] = {
114 		.name  = "service_relocated_descriptor",
115 		.init  = NULL,
116 		.print = NULL,
117 		.free  = NULL,
118 		.size  = 0,
119 	},
120 };
121 
dvb_extension_descriptor_init(struct dvb_v5_fe_parms * parms,const uint8_t * buf,struct dvb_desc * desc)122 int dvb_extension_descriptor_init(struct dvb_v5_fe_parms *parms,
123 				  const uint8_t *buf, struct dvb_desc *desc)
124 {
125 	struct dvb_extension_descriptor *ext = (void *)desc;
126 	unsigned char *p = (unsigned char *)buf;
127 	unsigned desc_type = *p;
128 	size_t size = 0;
129 	int desc_len  = ext->length - 1;
130 	dvb_desc_ext_init_func init;
131 
132 	ext->extension_code = desc_type;
133 	p++;
134 
135 	switch (parms->verbose) {
136 	case 0:
137 	case 1:
138 		break;
139 	case 2:
140 		if (dvb_ext_descriptors[desc_type].init)
141 			break;
142 		/* fall through */
143 	case 3:
144 		dvb_logwarn("%sextension descriptor %s type 0x%02x, size %d",
145 			dvb_ext_descriptors[desc_type].init ? "" : "Not handled ",
146 			dvb_ext_descriptors[desc_type].name, desc_type, desc_len);
147 		dvb_hexdump(parms, "content: ", p, desc_len);
148 	}
149 
150 	init = dvb_ext_descriptors[desc_type].init;
151 	if (init)
152 		size = dvb_ext_descriptors[desc_type].size;
153 	if (!size)
154 		size = desc_len;
155 
156 	ext->descriptor = calloc(1, size);
157 
158 	if (init) {
159 		if (init(parms, p, ext, ext->descriptor) != 0)
160 			return -1;
161 	}
162 	else
163 		memcpy(ext->descriptor, p, size);
164 	return 0;
165 }
166 
dvb_extension_descriptor_free(struct dvb_desc * descriptor)167 void dvb_extension_descriptor_free(struct dvb_desc *descriptor)
168 {
169 	struct dvb_extension_descriptor *ext = (void *)descriptor;
170 	uint8_t type = ext->extension_code;
171 
172 	if (!ext->descriptor)
173 		return;
174 
175 	if (dvb_ext_descriptors[type].free)
176 		dvb_ext_descriptors[type].free(ext->descriptor);
177 
178 	free(ext->descriptor);
179 }
180 
dvb_extension_descriptor_print(struct dvb_v5_fe_parms * parms,const struct dvb_desc * desc)181 void dvb_extension_descriptor_print(struct dvb_v5_fe_parms *parms,
182 				const struct dvb_desc *desc)
183 {
184 	struct dvb_extension_descriptor *ext = (void *)desc;
185 	uint8_t type = ext->extension_code;
186 	dvb_loginfo("|           descriptor %s type 0x%02x",
187 		dvb_ext_descriptors[type].name, type);
188 
189 	if (dvb_ext_descriptors[type].print)
190 		dvb_ext_descriptors[type].print(parms, ext, ext->descriptor);
191 }
192