• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2013-2014 - Andre Roth <neolynx@gmail.com>
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/mgt.h>
21 #include <libdvbv5/descriptors.h>
22 #include <libdvbv5/dvb-fe.h>
23 
24 #if __GNUC__ >= 9
25 #pragma GCC diagnostic ignored "-Waddress-of-packed-member"
26 #endif
27 
atsc_table_mgt_init(struct dvb_v5_fe_parms * parms,const uint8_t * buf,ssize_t buflen,struct atsc_table_mgt ** table)28 ssize_t atsc_table_mgt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
29 		ssize_t buflen, struct atsc_table_mgt **table)
30 {
31 	const uint8_t *p = buf, *endbuf = buf + buflen;
32 	struct atsc_table_mgt *mgt;
33 	struct atsc_table_mgt_table **head;
34 	struct dvb_desc **head_desc;
35 	size_t size;
36 	int i = 0;
37 
38 	size = offsetof(struct atsc_table_mgt, table);
39 	if (p + size > endbuf) {
40 		dvb_logerr("%s: short read %zd/%zd bytes", __func__,
41 			   endbuf - p, size);
42 		return -1;
43 	}
44 
45 	if (buf[0] != ATSC_TABLE_MGT) {
46 		dvb_logerr("%s: invalid marker 0x%02x, should be 0x%02x",
47 				__func__, buf[0], ATSC_TABLE_MGT);
48 		return -2;
49 	}
50 
51 	if (!*table) {
52 		*table = calloc(sizeof(struct atsc_table_mgt), 1);
53 		if (!*table) {
54 			dvb_logerr("%s: out of memory", __func__);
55 			return -3;
56 		}
57 	}
58 	mgt = *table;
59 	memcpy(mgt, p, size);
60 	p += size;
61 	dvb_table_header_init(&mgt->header);
62 
63 	bswap16(mgt->tables);
64 
65 	/* find end of curent lists */
66 	head_desc = &mgt->descriptor;
67 	while (*head_desc != NULL)
68 		head_desc = &(*head_desc)->next;
69 	head = &mgt->table;
70 	while (*head != NULL)
71 		head = &(*head)->next;
72 
73 	while (i++ < mgt->tables && p < endbuf) {
74 		struct atsc_table_mgt_table *table;
75 
76 		size = offsetof(struct atsc_table_mgt_table, descriptor);
77 		if (p + size > endbuf) {
78 			dvb_logerr("%s: short read %zd/%zd bytes", __func__,
79 				   endbuf - p, size);
80 			return -4;
81 		}
82 		table = (struct atsc_table_mgt_table *) malloc(sizeof(struct atsc_table_mgt_table));
83 		if (!table) {
84 			dvb_logerr("%s: out of memory", __func__);
85 			return -5;
86 		}
87 		memcpy(table, p, size);
88 		p += size;
89 
90 		bswap16(table->type);
91 		bswap16(table->bitfield);
92 		bswap16(table->bitfield2);
93 		bswap32(table->size);
94 		table->descriptor = NULL;
95 		table->next = NULL;
96 
97 		*head = table;
98 		head = &(*head)->next;
99 
100 		/* parse the descriptors */
101 		size = table->desc_length;
102 		if (p + size > endbuf) {
103 			dvb_logerr("%s: short read %zd/%zd bytes", __func__,
104 				   endbuf - p, size);
105 			return -6;
106 		}
107 		if (dvb_desc_parse(parms, p, size,
108 					&table->descriptor) != 0) {
109 			return -7;
110 		}
111 
112 		p += size;
113 	}
114 
115 	/* TODO: parse MGT descriptors here into head_desc */
116 
117 	return p - buf;
118 }
119 
atsc_table_mgt_free(struct atsc_table_mgt * mgt)120 void atsc_table_mgt_free(struct atsc_table_mgt *mgt)
121 {
122 	struct atsc_table_mgt_table *table = mgt->table;
123 
124 	dvb_desc_free(&mgt->descriptor);
125 	while (table) {
126 		struct atsc_table_mgt_table *tmp = table;
127 
128 		dvb_desc_free((struct dvb_desc **) &table->descriptor);
129 		table = table->next;
130 		free(tmp);
131 	}
132 	free(mgt);
133 }
134 
atsc_table_mgt_print(struct dvb_v5_fe_parms * parms,struct atsc_table_mgt * mgt)135 void atsc_table_mgt_print(struct dvb_v5_fe_parms *parms, struct atsc_table_mgt *mgt)
136 {
137 	const struct atsc_table_mgt_table *table = mgt->table;
138 	uint16_t tables = 0;
139 
140 	dvb_loginfo("MGT");
141 	ATSC_TABLE_HEADER_PRINT(parms, mgt);
142 	dvb_loginfo("| tables           %d", mgt->tables);
143 	while (table) {
144                 dvb_loginfo("|- type %04x    %d", table->type, table->pid);
145                 dvb_loginfo("|  one          %d", table->one);
146                 dvb_loginfo("|  one2         %d", table->one2);
147                 dvb_loginfo("|  type version %d", table->type_version);
148                 dvb_loginfo("|  size         %d", table->size);
149                 dvb_loginfo("|  one3         %d", table->one3);
150                 dvb_loginfo("|  desc_length  %d", table->desc_length);
151 		dvb_desc_print(parms, table->descriptor);
152 		table = table->next;
153 		tables++;
154 	}
155 	dvb_loginfo("|_  %d tables", tables);
156 }
157 
158