Ejemplo n.º 1
0
static int convert_file(struct arguments *args)
{
	struct dvb_file *dvb_file = NULL;
	int ret;

	printf(_("Reading file %s\n"), args->input_file);

	dvb_file = dvb_read_file_format(args->input_file, args->delsys,
				    args->input_format);
	if (!dvb_file) {
		fprintf(stderr, _("Error reading file %s\n"), args->input_file);
		return -1;
	}

	printf(_("Writing file %s\n"), args->output_file);
	ret = dvb_write_file_format(args->output_file, dvb_file,
				    args->delsys, args->output_format);
	dvb_file_free(dvb_file);

	return ret;
}
Ejemplo n.º 2
0
static int parse(struct arguments *args,
		 struct dvb_v5_fe_parms *parms,
		 char *channel,
		 int *vpid, int *apid, int *sid)
{
	struct dvb_file *dvb_file;
	struct dvb_entry *entry;
	int i;
	uint32_t sys;

	/* This is used only when reading old formats */
	switch (parms->current_sys) {
	case SYS_DVBT:
	case SYS_DVBS:
	case SYS_DVBC_ANNEX_A:
	case SYS_ATSC:
		sys = parms->current_sys;
		break;
	case SYS_DVBC_ANNEX_C:
		sys = SYS_DVBC_ANNEX_A;
		break;
	case SYS_DVBC_ANNEX_B:
		sys = SYS_ATSC;
		break;
	case SYS_ISDBT:
		sys = SYS_DVBT;
		break;
	default:
		sys = SYS_UNDEFINED;
		break;
	}
	dvb_file = read_file_format(args->confname, sys,
				    args->input_format);
	if (!dvb_file)
		return -2;

	for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
		if (!strcmp(entry->channel, channel))
			break;
		if (entry->vchannel && !strcmp(entry->vchannel, channel))
			break;
	}
	/*
	 * Give a second shot, using a case insensitive seek
	 */
	if (!entry) {
		for (entry = dvb_file->first_entry; entry != NULL;
		     entry = entry->next) {
			if (!strcasecmp(entry->channel, channel))
				break;
		}
	}
	if (!entry) {
		ERROR("Can't find channel");
		return -3;
	}

	if (entry->video_pid) {
		if (args->n_vpid < entry->video_pid_len)
			*vpid = entry->video_pid[args->n_vpid];
		else
			*vpid = entry->video_pid[0];
	}
	if (entry->audio_pid) {
		if (args->n_apid < entry->audio_pid_len)
			*apid = entry->audio_pid[args->n_apid];
		else
		*apid = entry->audio_pid[0];
	}
	if (entry->other_el_pid) {
		int i, type = -1;
		for (i = 0; i < entry->other_el_pid_len; i++) {
			if (type != entry->other_el_pid[i].type) {
				type = entry->other_el_pid[i].type;
				if (i)
					printf("\n");
				printf("service has pid type %02x: ", type);
			}
			printf(" %d", entry->other_el_pid[i].pid);
		}
		printf("\n");
	}
	*sid = entry->service_id;

	/* First of all, set the delivery system */
	for (i = 0; i < entry->n_props; i++)
		if (entry->props[i].cmd == DTV_DELIVERY_SYSTEM)
			dvb_set_compat_delivery_system(parms,
						       entry->props[i].u.data);

	/* Copy data into parms */
	for (i = 0; i < entry->n_props; i++) {
		uint32_t data = entry->props[i].u.data;
		/* Don't change the delivery system */
		if (entry->props[i].cmd == DTV_DELIVERY_SYSTEM)
			continue;
		dvb_fe_store_parm(parms, entry->props[i].cmd, data);
		if (parms->current_sys == SYS_ISDBT) {
			dvb_fe_store_parm(parms, DTV_ISDBT_PARTIAL_RECEPTION, 0);
			dvb_fe_store_parm(parms, DTV_ISDBT_SOUND_BROADCASTING, 0);
			dvb_fe_store_parm(parms, DTV_ISDBT_LAYER_ENABLED, 0x07);
			if (entry->props[i].cmd == DTV_CODE_RATE_HP) {
				dvb_fe_store_parm(parms, DTV_ISDBT_LAYERA_FEC,
						  data);
				dvb_fe_store_parm(parms, DTV_ISDBT_LAYERB_FEC,
						  data);
				dvb_fe_store_parm(parms, DTV_ISDBT_LAYERC_FEC,
						  data);
			} else if (entry->props[i].cmd == DTV_MODULATION) {
				dvb_fe_store_parm(parms,
						  DTV_ISDBT_LAYERA_MODULATION,
						  data);
				dvb_fe_store_parm(parms,
						  DTV_ISDBT_LAYERB_MODULATION,
						  data);
				dvb_fe_store_parm(parms,
						  DTV_ISDBT_LAYERC_MODULATION,
						  data);
			}
		}
		if (parms->current_sys == SYS_ATSC &&
		    entry->props[i].cmd == DTV_MODULATION) {
			if (data != VSB_8 && data != VSB_16)
				dvb_fe_store_parm(parms,
						  DTV_DELIVERY_SYSTEM,
						  SYS_DVBC_ANNEX_B);
		}
	}

#if 0
	/* HACK to test the write file function */
	write_dvb_file("dvb_channels.conf", dvb_file);
#endif

	dvb_file_free(dvb_file);
	return 0;
}
Ejemplo n.º 3
0
static int run_scan(struct arguments *args,
		    struct dvb_v5_fe_parms *parms)
{
	struct dvb_file *dvb_file = NULL, *dvb_file_new = NULL;
	struct dvb_entry *entry;
	int i, rc, count = 0, dmx_fd, shift;
	uint32_t freq, sys;

	/* This is used only when reading old formats */
	switch (parms->current_sys) {
	case SYS_DVBT:
	case SYS_DVBS:
	case SYS_DVBC_ANNEX_A:
	case SYS_ATSC:
		sys = parms->current_sys;
		break;
	case SYS_DVBC_ANNEX_C:
		sys = SYS_DVBC_ANNEX_A;
		break;
	case SYS_DVBC_ANNEX_B:
		sys = SYS_ATSC;
		break;
	case SYS_ISDBT:
		sys = SYS_DVBT;
		break;
	default:
		sys = SYS_UNDEFINED;
		break;
	}
	dvb_file = dvb_read_file_format(args->confname, sys,
				    args->input_format);
	if (!dvb_file)
		return -2;

	dmx_fd = open(args->demux_dev, O_RDWR);
	if (dmx_fd < 0) {
		perror("openening pat demux failed");
		return -3;
	}

	for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
		struct dvb_v5_descriptors *dvb_desc = NULL;

		/* First of all, set the delivery system */
		for (i = 0; i < entry->n_props; i++)
			if (entry->props[i].cmd == DTV_DELIVERY_SYSTEM)
				dvb_set_compat_delivery_system(parms,
							       entry->props[i].u.data);

		/* Copy data into parms */
		for (i = 0; i < entry->n_props; i++) {
			uint32_t data = entry->props[i].u.data;

			/* Don't change the delivery system */
			if (entry->props[i].cmd == DTV_DELIVERY_SYSTEM)
				continue;

			dvb_fe_store_parm(parms, entry->props[i].cmd, data);
			if (parms->current_sys == SYS_ISDBT) {
				dvb_fe_store_parm(parms, DTV_ISDBT_PARTIAL_RECEPTION, 0);
				dvb_fe_store_parm(parms, DTV_ISDBT_SOUND_BROADCASTING, 0);
				dvb_fe_store_parm(parms, DTV_ISDBT_LAYER_ENABLED, 0x07);
				if (entry->props[i].cmd == DTV_CODE_RATE_HP) {
					dvb_fe_store_parm(parms, DTV_ISDBT_LAYERA_FEC,
							data);
					dvb_fe_store_parm(parms, DTV_ISDBT_LAYERB_FEC,
							data);
					dvb_fe_store_parm(parms, DTV_ISDBT_LAYERC_FEC,
							data);
				} else if (entry->props[i].cmd == DTV_MODULATION) {
					dvb_fe_store_parm(parms,
							DTV_ISDBT_LAYERA_MODULATION,
							data);
					dvb_fe_store_parm(parms,
							DTV_ISDBT_LAYERB_MODULATION,
							data);
					dvb_fe_store_parm(parms,
							DTV_ISDBT_LAYERC_MODULATION,
							data);
				}
			}
			if (parms->current_sys == SYS_ATSC &&
			    entry->props[i].cmd == DTV_MODULATION) {
				if (data != VSB_8 && data != VSB_16)
					dvb_fe_store_parm(parms,
							DTV_DELIVERY_SYSTEM,
							SYS_DVBC_ANNEX_B);
			}
		}

		/*
		 * If the channel file has duplicated frequencies, or some
		 * entries without any frequency at all, discard.
		 */
		freq = 0;
		for (i = 0; i < entry->n_props; i++) {
			if (entry->props[i].cmd == DTV_FREQUENCY) {
				freq = entry->props[i].u.data;
				break;
			}
		}
		if (!freq)
			continue;
		shift = estimate_freq_shift(parms);
		if (dvb_desc && !new_freq_is_needed(dvb_file->first_entry, entry,
					freq, dvb_desc->nit_table.pol, shift))
			continue;

		rc = dvb_fe_set_parms(parms);
		if (rc < 0) {
			PERROR("dvb_fe_set_parms failed");
			return -1;
		}

		/* As the DVB core emulates it, better to always use auto */
		dvb_fe_store_parm(parms, DTV_INVERSION, INVERSION_AUTO);

		dvb_fe_retrieve_parm(parms, DTV_FREQUENCY, &freq);
		count++;
		dvb_log("Scanning frequency #%d %d", count, freq);
		if (verbose)
			dvb_fe_prt_parms(parms);

		rc = check_frontend(args, parms);
		if (rc < 0)
			continue;

		dvb_desc = dvb_get_ts_tables(parms, dmx_fd,
					     parms->current_sys,
					     args->other_nit,
					     args->timeout_multiply,
					     verbose);
		if (!dvb_desc)
			continue;

		for (i = 0; i < dvb_desc->sdt_table.service_table_len; i++) {
			struct service_table *service_table = &dvb_desc->sdt_table.service_table[i];

			entry->vchannel = dvb_vchannel(dvb_desc, i);
			printf("Service #%d (%d)", i,
				service_table->service_id);
			if (service_table->service_name)
				printf(" %s", service_table->service_name);
			if (entry->vchannel)
				printf(" channel %s", entry->vchannel);
			printf("\n");
		}

		store_dvb_channel(&dvb_file_new, parms, dvb_desc,
				  args->get_detected, args->get_nit);

		if (!args->dont_add_new_freqs)
			add_other_freq_entries(dvb_file, parms, dvb_desc);

		dvb_free_ts_tables(dvb_desc);
	}

	if (dvb_file_new)
		write_file_format(args->output, dvb_file_new,
				  parms->current_sys, args->output_format);

	dvb_file_free(dvb_file);
	if (dvb_file_new)
		dvb_file_free(dvb_file_new);

	close(dmx_fd);
	return 0;
}
Ejemplo n.º 4
0
static int run_scan(struct arguments *args,
		    struct dvb_v5_fe_parms *parms)
{
	struct dvb_file *dvb_file = NULL, *dvb_file_new = NULL;
	struct dvb_entry *entry;
	int count = 0, dmx_fd, shift;
	uint32_t freq, sys;
	enum dvb_sat_polarization pol;

	/* This is used only when reading old formats */
	switch (parms->current_sys) {
	case SYS_DVBT:
	case SYS_DVBS:
	case SYS_DVBC_ANNEX_A:
	case SYS_ATSC:
		sys = parms->current_sys;
		break;
	case SYS_DVBC_ANNEX_C:
		sys = SYS_DVBC_ANNEX_A;
		break;
	case SYS_DVBC_ANNEX_B:
		sys = SYS_ATSC;
		break;
	case SYS_ISDBT:
	case SYS_DTMB:
		sys = SYS_DVBT;
		break;
	default:
		sys = SYS_UNDEFINED;
		break;
	}
	dvb_file = dvb_read_file_format(args->confname, sys,
				    args->input_format);
	if (!dvb_file)
		return -2;

	dmx_fd = open(args->demux_dev, O_RDWR);
	if (dmx_fd < 0) {
		perror(_("openening pat demux failed"));
		return -3;
	}

	for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
		struct dvb_v5_descriptors *dvb_scan_handler = NULL;
		uint32_t stream_id;

		/*
		 * If the channel file has duplicated frequencies, or some
		 * entries without any frequency at all, discard.
		 */
		if (dvb_retrieve_entry_prop(entry, DTV_FREQUENCY, &freq))
			continue;
		shift = dvb_estimate_freq_shift(parms);

		if (dvb_retrieve_entry_prop(entry, DTV_POLARIZATION, &pol))
			pol = POLARIZATION_OFF;

		if (dvb_retrieve_entry_prop(entry, DTV_STREAM_ID, &stream_id))
			stream_id = NO_STREAM_ID_FILTER;

		if (!dvb_new_entry_is_needed(dvb_file->first_entry, entry,
						  freq, shift, pol, stream_id))
			continue;

		count++;
		dvb_log(_("Scanning frequency #%d %d"), count, freq);

		/*
		 * update params->lnb only if it differs from entry->lnb
		 * (and "--lnbf" option was not provided),
		 * to avoid linear search of LNB types for every entries.
		 */
		if (!args->lnb_name && entry->lnb &&
		    (!parms->lnb || strcasecmp(entry->lnb, parms->lnb->alias)))
			parms->lnb = dvb_sat_get_lnb(dvb_sat_search_lnb(entry->lnb));

		/*
		 * Run the scanning logic
		 */

		dvb_scan_handler = dvb_scan_transponder(parms, entry, dmx_fd,
							&check_frontend, args,
							args->other_nit,
							args->timeout_multiply);

		if (parms->abort) {
			dvb_scan_free_handler_table(dvb_scan_handler);
			break;
		}
		if (!dvb_scan_handler)
			continue;

		/*
		 * Store the service entry
		 */
		dvb_store_channel(&dvb_file_new, parms, dvb_scan_handler,
				  args->get_detected, args->get_nit);

		/*
		 * Add new transponders based on NIT table information
		 */
		if (!args->dont_add_new_freqs)
			dvb_add_scaned_transponders(parms, dvb_scan_handler,
						    dvb_file->first_entry, entry);

		/*
		 * Free the scan handler associated with the transponder
		 */

		dvb_scan_free_handler_table(dvb_scan_handler);
	}

	if (dvb_file_new)
		dvb_write_file_format(args->output, dvb_file_new,
				      parms->current_sys, args->output_format);

	dvb_file_free(dvb_file);
	if (dvb_file_new)
		dvb_file_free(dvb_file_new);

	close(dmx_fd);
	return 0;
}
Ejemplo n.º 5
0
static int run_scan(struct arguments *args,
		    struct dvb_v5_fe_parms *parms)
{
	struct dvb_file *dvb_file = NULL, *dvb_file_new = NULL;
	struct dvb_entry *entry;
	int count = 0, dmx_fd, shift;
	uint32_t freq, sys;
	enum dvb_sat_polarization pol;

	/* This is used only when reading old formats */
	switch (parms->current_sys) {
	case SYS_DVBT:
	case SYS_DVBS:
	case SYS_DVBC_ANNEX_A:
	case SYS_ATSC:
		sys = parms->current_sys;
		break;
	case SYS_DVBC_ANNEX_C:
		sys = SYS_DVBC_ANNEX_A;
		break;
	case SYS_DVBC_ANNEX_B:
		sys = SYS_ATSC;
		break;
	case SYS_ISDBT:
		sys = SYS_DVBT;
		break;
	default:
		sys = SYS_UNDEFINED;
		break;
	}
	dvb_file = dvb_read_file_format(args->confname, sys,
				    args->input_format);
	if (!dvb_file)
		return -2;

	dmx_fd = open(args->demux_dev, O_RDWR);
	if (dmx_fd < 0) {
		perror("openening pat demux failed");
		return -3;
	}

	for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
		struct dvb_v5_descriptors *dvb_scan_handler = NULL;

		/*
		 * If the channel file has duplicated frequencies, or some
		 * entries without any frequency at all, discard.
		 */
		if (retrieve_entry_prop(entry, DTV_FREQUENCY, &freq))
			continue;

		shift = estimate_freq_shift(parms);

		if (retrieve_entry_prop(entry, DTV_POLARIZATION, &pol))
			pol = POLARIZATION_OFF;

		if (!new_freq_is_needed(dvb_file->first_entry, entry,
					freq, pol, shift))
			continue;

		count++;
		dvb_log("Scanning frequency #%d %d", count, freq);

		/*
		 * Run the scanning logic
		 */

		dvb_scan_handler = dvb_scan_transponder(parms, entry, dmx_fd,
							&check_frontend, args,
							args->other_nit,
							args->timeout_multiply);

		if (parms->abort) {
			dvb_scan_free_handler_table(dvb_scan_handler);
			break;
		}
		if (!dvb_scan_handler)
			continue;

		/*
		 * Store the service entry
		 */
		store_dvb_channel(&dvb_file_new, parms, dvb_scan_handler,
				  args->get_detected, args->get_nit);

		/*
		 * Add new transponders based on NIT table information
		 */
		if (!args->dont_add_new_freqs)
			dvb_add_scaned_transponders(parms, dvb_scan_handler,
						    dvb_file->first_entry, entry);

		/*
		 * Free the scan handler associated with the transponder
		 */

		dvb_scan_free_handler_table(dvb_scan_handler);
	}

	if (dvb_file_new)
		write_file_format(args->output, dvb_file_new,
				  parms->current_sys, args->output_format);

	dvb_file_free(dvb_file);
	if (dvb_file_new)
		dvb_file_free(dvb_file_new);

	close(dmx_fd);
	return 0;
}
Ejemplo n.º 6
0
static int parse(struct arguments *args,
		 struct dvb_v5_fe_parms *parms,
		 char *channel,
		 int *vpid, int *apid, int *sid)
{
	struct dvb_file *dvb_file;
	struct dvb_entry *entry;
	int i;
	uint32_t sys;

	/* This is used only when reading old formats */
	switch (parms->current_sys) {
	case SYS_DVBT:
	case SYS_DVBS:
	case SYS_DVBC_ANNEX_A:
	case SYS_ATSC:
		sys = parms->current_sys;
		break;
	case SYS_DVBC_ANNEX_C:
		sys = SYS_DVBC_ANNEX_A;
		break;
	case SYS_DVBC_ANNEX_B:
		sys = SYS_ATSC;
		break;
	case SYS_ISDBT:
	case SYS_DTMB:
		sys = SYS_DVBT;
		break;
	default:
		sys = SYS_UNDEFINED;
		break;
	}
	dvb_file = dvb_read_file_format(args->confname, sys,
				    args->input_format);
	if (!dvb_file)
		return -2;

	for (entry = dvb_file->first_entry; entry != NULL; entry = entry->next) {
		if (entry->channel && !strcmp(entry->channel, channel))
			break;
		if (entry->vchannel && !strcmp(entry->vchannel, channel))
			break;
	}
	/*
	 * Give a second shot, using a case insensitive seek
	 */
	if (!entry) {
		for (entry = dvb_file->first_entry; entry != NULL;
		     entry = entry->next) {
			if (entry->channel && !strcasecmp(entry->channel, channel))
				break;
		}
	}

	/*
	 * When this tool is used to just tune to a channel, to monitor it or
	 * to capture all PIDs, all it needs is a frequency.
	 * So, let the tool to accept a frequency as the tuning channel on those
	 * cases.
	 * This way, a file in "channel" format can be used instead of a zap file.
	 * It is also easier to use it for testing purposes.
	 */
	if (!entry && (args->traffic_monitor || args->all_pids || args->exit_after_tuning)) {
		uint32_t f, freq = atoi(channel);
		if (freq) {
			for (entry = dvb_file->first_entry; entry != NULL;
			entry = entry->next) {
				dvb_retrieve_entry_prop(entry, DTV_FREQUENCY, &f);
				if (f == freq)
					break;
			}

		}
	}

	if (!entry) {
		ERROR(_("Can't find channel"));
		dvb_file_free(dvb_file);
		return -3;
	}

	/*
	 * Both the DVBv5 format and the command line parameters may
	 * specify the LNBf. If both have the definition, use the one
	 * provided by the command line parameter, overriding the one
	 * stored in the channel file.
	 */
	if (entry->lnb && !parms->lnb) {
		int lnb = dvb_sat_search_lnb(entry->lnb);
		if (lnb == -1) {
			PERROR(_("unknown LNB %s\n"), entry->lnb);
			dvb_file_free(dvb_file);
			return -1;
		}
		parms->lnb = dvb_sat_get_lnb(lnb);
	}

	if (entry->video_pid) {
		if (args->n_vpid < entry->video_pid_len)
			*vpid = entry->video_pid[args->n_vpid];
		else
			*vpid = entry->video_pid[0];
	}
	if (entry->audio_pid) {
		if (args->n_apid < entry->audio_pid_len)
			*apid = entry->audio_pid[args->n_apid];
		else
		*apid = entry->audio_pid[0];
	}
	if (entry->other_el_pid) {
		int i, type = -1;
		for (i = 0; i < entry->other_el_pid_len; i++) {
			if (type != entry->other_el_pid[i].type) {
				type = entry->other_el_pid[i].type;
				if (i)
					fprintf(stderr, "\n");
				fprintf(stderr, _("service has pid type %02x: "), type);
			}
			fprintf(stderr, " %d", entry->other_el_pid[i].pid);
		}
		fprintf(stderr, "\n");
	}
	*sid = entry->service_id;

        /* First of all, set the delivery system */
	dvb_retrieve_entry_prop(entry, DTV_DELIVERY_SYSTEM, &sys);
	dvb_set_compat_delivery_system(parms, sys);

	/* Copy data into parms */
	for (i = 0; i < entry->n_props; i++) {
		uint32_t data = entry->props[i].u.data;
		/* Don't change the delivery system */
		if (entry->props[i].cmd == DTV_DELIVERY_SYSTEM)
			continue;
		dvb_fe_store_parm(parms, entry->props[i].cmd, data);
		if (parms->current_sys == SYS_ISDBT) {
			dvb_fe_store_parm(parms, DTV_ISDBT_PARTIAL_RECEPTION, 0);
			dvb_fe_store_parm(parms, DTV_ISDBT_SOUND_BROADCASTING, 0);
			dvb_fe_store_parm(parms, DTV_ISDBT_LAYER_ENABLED, 0x07);
			if (entry->props[i].cmd == DTV_CODE_RATE_HP) {
				dvb_fe_store_parm(parms, DTV_ISDBT_LAYERA_FEC,
						  data);
				dvb_fe_store_parm(parms, DTV_ISDBT_LAYERB_FEC,
						  data);
				dvb_fe_store_parm(parms, DTV_ISDBT_LAYERC_FEC,
						  data);
			} else if (entry->props[i].cmd == DTV_MODULATION) {
				dvb_fe_store_parm(parms,
						  DTV_ISDBT_LAYERA_MODULATION,
						  data);
				dvb_fe_store_parm(parms,
						  DTV_ISDBT_LAYERB_MODULATION,
						  data);
				dvb_fe_store_parm(parms,
						  DTV_ISDBT_LAYERC_MODULATION,
						  data);
			}
		}
		if (parms->current_sys == SYS_ATSC &&
		    entry->props[i].cmd == DTV_MODULATION) {
			if (data != VSB_8 && data != VSB_16)
				dvb_fe_store_parm(parms,
						  DTV_DELIVERY_SYSTEM,
						  SYS_DVBC_ANNEX_B);
		}
	}

	dvb_file_free(dvb_file);
	return 0;
}
Ejemplo n.º 7
0
/*
 * Generic parse function for all formats each channel is contained into
 * just one line.
 */
struct dvb_file *parse_format_oneline(const char *fname,
				      uint32_t delsys,
				      const struct parse_file *parse_file)
{
	const char *delimiter = parse_file->delimiter;
	const struct parse_struct *formats = parse_file->formats;
	char *buf = NULL, *p;
	size_t size = 0;
	int len = 0;
	int i, j, line = 0;
	struct dvb_file *dvb_file;
	FILE *fd;
	const struct parse_struct *fmt;
	struct dvb_entry *entry = NULL;
	const struct parse_table *table;
	char err_msg[80];
	int has_inversion;

	dvb_file = calloc(sizeof(*dvb_file), 1);
	if (!dvb_file) {
		perror("Allocating memory for dvb_file");
		return NULL;
	}

	fd = fopen(fname, "r");
	if (!fd) {
		perror(fname);
		return NULL;
	}

	do {
		len = getline(&buf, &size, fd);
		if (len <= 0)
			break;
		line++;

		p = buf;
		while (*p == ' ')
			p++;
		if (*p == '\n' || *p == '#' || *p == '\a' || *p == '\0')
			continue;

		if (parse_file->has_delsys_id) {
			p = strtok(p, delimiter);
			if (!p) {
				sprintf(err_msg, "unknown delivery system type for %s",
					p);
				goto error;
			}

			/* Parse the type of the delivery system */
			for (i = 0; formats[i].id != NULL; i++) {
				if (!strcmp(p, formats[i].id))
					break;
			}
		} else {
			/* Seek for the delivery system */
			for (i = 0; formats[i].delsys != 0; i++) {
				if (formats[i].delsys == delsys)
					break;
			}
		}
		if (i == ARRAY_SIZE(formats))
			goto error;


		fmt = &formats[i];
		if (!entry) {
			dvb_file->first_entry = calloc(sizeof(*entry), 1);
			entry = dvb_file->first_entry;
		} else {
			entry->next = calloc(sizeof(*entry), 1);
			entry = entry->next;
		}
		entry->sat_number = -1;
		entry->props[entry->n_props].cmd = DTV_DELIVERY_SYSTEM;
		entry->props[entry->n_props++].u.data = fmt->delsys;
		has_inversion = 0;
		for (i = 0; i < fmt->size; i++) {
			table = &fmt->table[i];
			if (delsys && !i) {
				p = strtok(p, delimiter);
			} else
				p = strtok(NULL, delimiter);
			if (!p) {
				sprintf(err_msg, "parameter %i (%s) missing",
					i, parm_name(table));
				goto error;
			}
			if (table->size) {
				for (j = 0; j < table->size; j++)
					if (!strcasecmp(table->table[j], p))
						break;
				if (j == table->size) {
					sprintf(err_msg, "parameter %s invalid: %s",
						parm_name(table), p);
					goto error;
				}
				if (table->prop == DTV_BANDWIDTH_HZ)
					j = fe_bandwidth_name[j];
				if (table->prop == DTV_POLARIZATION) {
					entry->pol = j;
				} else {
					entry->props[entry->n_props].cmd = table->prop;
					entry->props[entry->n_props++].u.data = j;
				}
			} else {
				long v = atol(p);
				if (table->mult_factor)
					v *= table->mult_factor;

				switch (table->prop) {
				case DTV_VIDEO_PID:
					entry->video_pid = calloc(sizeof(*entry->video_pid), 1);
					entry->video_pid_len = 1;
					entry->video_pid[0] = v;
					break;
				case DTV_AUDIO_PID:
					entry->audio_pid = calloc(sizeof(*entry->audio_pid), 1);
					entry->audio_pid_len = 1;
					entry->audio_pid[0] = v;
					break;
				case DTV_SERVICE_ID:
					entry->service_id = v;
					break;
				case DTV_CH_NAME:
					entry->channel = calloc(strlen(p) + 1, 1);
					strcpy(entry->channel, p);
					break;
				default:
					entry->props[entry->n_props].cmd = table->prop;
					entry->props[entry->n_props++].u.data = v;
				}
			}
			if (table->prop == DTV_INVERSION)
				has_inversion = 1;
		}
		if (!has_inversion) {
			entry->props[entry->n_props].cmd = DTV_INVERSION;
			entry->props[entry->n_props++].u.data = INVERSION_AUTO;
		}

	} while (1);
	fclose (fd);
	return dvb_file;

error:
	fprintf (stderr, "ERROR %s while parsing line %d of %s\n",
		 err_msg, line, fname);
	dvb_file_free(dvb_file);
	fclose(fd);
	return NULL;
}
Ejemplo n.º 8
0
struct dvb_file *read_dvb_file(const char *fname)
{
	char *buf = NULL, *p, *key, *value;
	size_t size = 0;
	int len = 0;
	int line = 0, rc;
	struct dvb_file *dvb_file;
	FILE *fd;
	struct dvb_entry *entry = NULL;
	char err_msg[80];

	dvb_file = calloc(sizeof(*dvb_file), 1);
	if (!dvb_file) {
		perror("Allocating memory for dvb_file");
		return NULL;
	}

	fd = fopen(fname, "r");
	if (!fd) {
		perror(fname);
		return NULL;
	}

	do {
		len = getline(&buf, &size, fd);
		if (len <= 0)
			break;
		line++;
		p = buf;
		while (*p == ' ' || *p == '\t')
			p++;
		if (*p == '\n' || *p == '#' || *p == '\a' || *p == '\0')
			continue;

		if (*p == '[') {
			/* NEW Entry */
			if (!entry) {
				dvb_file->first_entry = calloc(sizeof(*entry), 1);
				entry = dvb_file->first_entry;
			} else {
				entry->next = calloc(sizeof(*entry), 1);
				entry = entry->next;
			}
			entry->sat_number = -1;
			p++;
			p = strtok(p, "]");
			if (!p) {
				sprintf(err_msg, "Missing channel group");
				goto error;
			}
			if (!strcasecmp(p, CHANNEL))
				p += strlen(CHANNEL);
			while (*p == ' ' || *p == '\t')
				p++;
			if (*p) {
				entry->channel = calloc(strlen(p) + 1, 1);
				strcpy(entry->channel, p);
			}
		} else {
			if (!entry) {
				sprintf(err_msg, "key/value without a channel group");
				goto error;
			}
			key = strtok(p, "=");
			if (!key) {
				sprintf(err_msg, "missing key");
				goto error;
			}
			p = &key[strlen(key) - 1];
			while ((p > key) && (*(p - 1) == ' ' || *(p - 1) == '\t'))
				p--;
			*p = 0;
			value = strtok(NULL, "\n");
			if (!value) {
				sprintf(err_msg, "missing value");
				goto error;
			}
			while (*value == ' ' || *value == '\t')
				value++;

			rc = fill_entry(entry, key, value);
			if (rc == -2) {
				sprintf(err_msg, "value %s is invalid for %s",
					value, key);
				goto error;
			} else if (rc == -2) {
				sprintf(err_msg, "key %s is unknown", key);
				goto error;
			}
		}
	} while (1);
	fclose(fd);
	return dvb_file;

error:
	fprintf (stderr, "ERROR %s while parsing line %d of %s\n",
		 err_msg, line, fname);
	dvb_file_free(dvb_file);
	fclose(fd);
	return NULL;
};