Ejemplo n.º 1
0
void dvb_table_sdt_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
			ssize_t buflen, uint8_t *table, ssize_t *table_length)
{
	const uint8_t *p = buf, *endbuf = buf + buflen - 4;
	struct dvb_table_sdt *sdt = (void *)table;
	struct dvb_table_sdt_service **head = &sdt->service;
	size_t size = offsetof(struct dvb_table_sdt, service);

	if (*table_length > 0) {
		/* find end of curent list */
		while (*head != NULL)
			head = &(*head)->next;
	} else {
		if (p + size > endbuf) {
			dvb_logerr("SDT table was truncated. Need %zu bytes, but has only %zu.",
					size, buflen);
			return;
		}
		memcpy(sdt, p, size);
		*table_length = sizeof(struct dvb_table_sdt);

		bswap16(sdt->network_id);

		sdt->service = NULL;
	}
	p += size;

	size = offsetof(struct dvb_table_sdt_service, descriptor);
	while (p + size <= endbuf) {
		struct dvb_table_sdt_service *service;

		service = malloc(sizeof(struct dvb_table_sdt_service));

		memcpy(service, p, size);
		p += size;

		bswap16(service->service_id);
		bswap16(service->bitfield);
		service->descriptor = NULL;
		service->next = NULL;

		*head = service;
		head = &(*head)->next;

		/* get the descriptors for each program */
		dvb_parse_descriptors(parms, p, service->section_length,
				      &service->descriptor);

		p += service->section_length;
	}
	if (endbuf - p)
		dvb_logerr("PAT table has %zu spurious bytes at the end.",
			   endbuf - p);
}
Ejemplo n.º 2
0
void atsc_table_vct_init(struct dvb_v5_fe_parms *parms, const uint8_t *buf,
			ssize_t buflen, uint8_t *table, ssize_t *table_length)
{
	const uint8_t *p = buf, *endbuf = buf + buflen - 4;
	struct atsc_table_vct *vct = (void *)table;
	struct atsc_table_vct_channel **head = &vct->channel;
	int i, n;
	size_t size = offsetof(struct atsc_table_vct, channel);

	if (p + size > endbuf) {
		dvb_logerr("VCT table was truncated. Need %zu bytes, but has only %zu.",
			   size, buflen);
		return;
	}

	if (*table_length > 0) {
		/* find end of curent list */
		while (*head != NULL)
			head = &(*head)->next;
	} else {
		memcpy(vct, p, size);

		*table_length = sizeof(struct atsc_table_vct);

		vct->channel = NULL;
		vct->descriptor = NULL;
	}
	p += size;

	size = offsetof(struct atsc_table_vct_channel, descriptor);
	for (n = 0; n < vct->num_channels_in_section; n++) {
		struct atsc_table_vct_channel *channel;

		if (p + size > endbuf) {
			dvb_logerr("VCT channel table is missing %d elements",
				   vct->num_channels_in_section - n + 1);
			vct->num_channels_in_section = n;
			break;
		}

		channel = malloc(sizeof(struct atsc_table_vct_channel));

		memcpy(channel, p, size);
		p += size;

		/* Fix endiannes of the copied fields */
		for (i = 0; i < ARRAY_SIZE(channel->__short_name); i++)
			bswap16(channel->__short_name[i]);

		bswap32(channel->carrier_frequency);
		bswap16(channel->channel_tsid);
		bswap16(channel->program_number);
		bswap32(channel->bitfield1);
		bswap16(channel->bitfield2);
		bswap16(channel->source_id);
		bswap16(channel->bitfield3);

		/* Short name is always UTF-16 */
		iconv_to_charset(parms, channel->short_name,
				 sizeof(channel->short_name),
				 (const unsigned char *)channel->__short_name,
				 sizeof(channel->__short_name),
				 "UTF-16",
				 output_charset);

		/* Fill descriptors */

		channel->descriptor = NULL;
		channel->next = NULL;

		*head = channel;
		head = &(*head)->next;

		/* get the descriptors for each program */
		dvb_parse_descriptors(parms, p, channel->descriptors_length,
				      &channel->descriptor);

		p += channel->descriptors_length;
	}

	/* Get extra descriptors */
	size = sizeof(union atsc_table_vct_descriptor_length);
	while (p + size <= endbuf) {
		union atsc_table_vct_descriptor_length *d = (void *)p;
		bswap16(d->descriptor_length);
		p += size;
		dvb_parse_descriptors(parms, p, d->descriptor_length,
				      &vct->descriptor);
	}
	if (endbuf - p)
		dvb_logerr("VCT table has %zu spurious bytes at the end.",
			   endbuf - p);
}