⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan.c

📁 关于dvb的应用程序代码
💻 C
📖 第 1 页 / 共 4 页
字号:
		warning("truncated section (PID 0x%04x, lenght %d)",			s->pid, section_length + 9);		return 0;	}	if (!get_bit(s->section_done, section_number)) {		set_bit (s->section_done, section_number);		debug("pid 0x%02x tid 0x%02x table_id_ext 0x%04x, "		    "%i/%i (version %i)\n",		    s->pid, table_id, table_id_ext, section_number,		    last_section_number, section_version_number);		switch (table_id) {		case 0x00:			verbose("PAT\n");			parse_pat (buf, section_length, table_id_ext);			break;		case 0x02:			verbose("PMT 0x%04x for service 0x%04x\n", s->pid, table_id_ext);			parse_pmt (buf, section_length, table_id_ext);			break;		case 0x41:			verbose("////////////////////////////////////////////// NIT other\n");		case 0x40:			verbose("NIT (%s TS)\n", table_id == 0x40 ? "actual":"other");			parse_nit (buf, section_length, table_id_ext);			break;		case 0x42:		case 0x46:			verbose("SDT (%s TS)\n", table_id == 0x42 ? "actual":"other");			parse_sdt (buf, section_length, table_id_ext);			break;		case 0xc8:		case 0xc9:			verbose("ATSC VCT\n");			parse_psip_vct(buf, section_length, table_id, table_id_ext);			break;		default:			;		};		for (i = 0; i <= last_section_number; i++)			if (get_bit (s->section_done, i) == 0)				break;		if (i > last_section_number)			s->sectionfilter_done = 1;	}	if (s->segmented) {		/* always wait for timeout; this is because we don't now how		 * many segments there are		 */		return 0;	}	else if (s->sectionfilter_done)		return 1;	return 0;}static int read_sections (struct section_buf *s){	int section_length, count;	if (s->sectionfilter_done && !s->segmented)		return 1;	/* the section filter API guarantess that we get one full section	 * per read(), provided that the buffer is large enough (it is)	 */	if (((count = read (s->fd, s->buf, sizeof(s->buf))) < 0) && errno == EOVERFLOW)		count = read (s->fd, s->buf, sizeof(s->buf));	if (count < 0) {		errorn("read_sections: read error");		return -1;	}	if (count < 4)		return -1;	section_length = ((s->buf[1] & 0x0f) << 8) | s->buf[2];	if (count != section_length + 3)		return -1;	if (parse_section(s) == 1)		return 1;	return 0;}static LIST_HEAD(running_filters);static LIST_HEAD(waiting_filters);static int n_running;#define MAX_RUNNING 27static struct pollfd poll_fds[MAX_RUNNING];static struct section_buf* poll_section_bufs[MAX_RUNNING];static void setup_filter (struct section_buf* s, const char *dmx_devname,			  int pid, int tid, int tid_ext,			  int run_once, int segmented, int timeout){	memset (s, 0, sizeof(struct section_buf));	s->fd = -1;	s->dmx_devname = dmx_devname;	s->pid = pid;	s->table_id = tid;	s->run_once = run_once;	s->segmented = segmented;	if (long_timeout)		s->timeout = 5 * timeout;	else		s->timeout = timeout;	s->table_id_ext = tid_ext;	s->section_version_number = -1;	INIT_LIST_HEAD (&s->list);}static void update_poll_fds(void){	struct list_head *p;	struct section_buf* s;	int i;	memset(poll_section_bufs, 0, sizeof(poll_section_bufs));	for (i = 0; i < MAX_RUNNING; i++)		poll_fds[i].fd = -1;	i = 0;	list_for_each (p, &running_filters) {		if (i >= MAX_RUNNING)			fatal("too many poll_fds\n");		s = list_entry (p, struct section_buf, list);		if (s->fd == -1)			fatal("s->fd == -1 on running_filters\n");		verbosedebug("poll fd %d\n", s->fd);		poll_fds[i].fd = s->fd;		poll_fds[i].events = POLLIN;		poll_fds[i].revents = 0;		poll_section_bufs[i] = s;		i++;	}	if (i != n_running)		fatal("n_running is hosed\n");}static int start_filter (struct section_buf* s){	struct dmx_sct_filter_params f;	if (n_running >= MAX_RUNNING)		goto err0;	if ((s->fd = open (s->dmx_devname, O_RDWR | O_NONBLOCK)) < 0)		goto err0;	verbosedebug("start filter pid 0x%04x table_id 0x%02x\n", s->pid, s->table_id);	memset(&f, 0, sizeof(f));	f.pid = (uint16_t) s->pid;	if (s->table_id < 0x100 && s->table_id > 0) {		f.filter.filter[0] = (uint8_t) s->table_id;		f.filter.mask[0]   = 0xff;	}	if (s->table_id_ext < 0x10000 && s->table_id_ext > 0) {		f.filter.filter[1] = (uint8_t) ((s->table_id_ext >> 8) & 0xff);		f.filter.filter[2] = (uint8_t) (s->table_id_ext & 0xff);		f.filter.mask[1] = 0xff;		f.filter.mask[2] = 0xff;	}	f.timeout = 0;	f.flags = DMX_IMMEDIATE_START | DMX_CHECK_CRC;	if (ioctl(s->fd, DMX_SET_FILTER, &f) == -1) {		errorn ("ioctl DMX_SET_FILTER failed");		goto err1;	}	s->sectionfilter_done = 0;	time(&s->start_time);	list_del_init (&s->list);  /* might be in waiting filter list */	list_add (&s->list, &running_filters);	n_running++;	update_poll_fds();	return 0;err1:	ioctl (s->fd, DMX_STOP);	close (s->fd);err0:	return -1;}static void stop_filter (struct section_buf *s){	verbosedebug("stop filter pid 0x%04x\n", s->pid);	ioctl (s->fd, DMX_STOP);	close (s->fd);	s->fd = -1;	list_del (&s->list);	s->running_time += time(NULL) - s->start_time;	n_running--;	update_poll_fds();}static void add_filter (struct section_buf *s){	verbosedebug("add filter pid 0x%04x\n", s->pid);	if (start_filter (s))		list_add_tail (&s->list, &waiting_filters);}static void remove_filter (struct section_buf *s){	verbosedebug("remove filter pid 0x%04x\n", s->pid);	stop_filter (s);	while (!list_empty(&waiting_filters)) {		struct list_head *next = waiting_filters.next;		s = list_entry (next, struct section_buf, list);		if (start_filter (s))			break;	};}static void read_filters (void){	struct section_buf *s;	int i, n, done;	n = poll(poll_fds, n_running, 1000);	if (n == -1)		errorn("poll");	for (i = 0; i < n_running; i++) {		s = poll_section_bufs[i];		if (!s)			fatal("poll_section_bufs[%d] is NULL\n", i);		if (poll_fds[i].revents)			done = read_sections (s) == 1;		else			done = 0; /* timeout */		if (done || time(NULL) > s->start_time + s->timeout) {			if (s->run_once) {				if (done)					verbosedebug("filter done pid 0x%04x\n", s->pid);				else					warning("filter timeout pid 0x%04x\n", s->pid);				remove_filter (s);			}		}	}}static int mem_is_zero (const void *mem, int size){	const char *p = mem;	int i;	for (i=0; i<size; i++) {		if (p[i] != 0x00)			return 0;	}	return 1;}static int switch_pos = 0;static int __tune_to_transponder (int frontend_fd, struct transponder *t){	struct dvb_frontend_parameters p;	fe_status_t s;	int i;	current_tp = t;	if (mem_is_zero (&t->param, sizeof(struct dvb_frontend_parameters)))		return -1;	memcpy (&p, &t->param, sizeof(struct dvb_frontend_parameters));	if (verbosity >= 1) {		dprintf(1, ">>> tune to: ");		dump_dvb_parameters (stderr, t);		if (t->last_tuning_failed)			dprintf(1, " (tuning failed)");		dprintf(1, "\n");	}	if (t->type == FE_QPSK) {		int hiband = 0;		if (lnb_type.switch_val && lnb_type.high_val &&			p.frequency >= lnb_type.switch_val)			hiband = 1;		setup_switch (frontend_fd,			      switch_pos,			      t->polarisation == POLARISATION_VERTICAL ? 0 : 1,			      hiband);		usleep(50000);		if (hiband)			p.frequency = abs(p.frequency - lnb_type.high_val);		else			p.frequency = abs(p.frequency - lnb_type.low_val);	}	if (ioctl(frontend_fd, FE_SET_FRONTEND, &p) == -1) {		errorn("Setting frontend parameters failed");		return -1;	}	for (i = 0; i < 10; i++) {		usleep (200000);		if (ioctl(frontend_fd, FE_READ_STATUS, &s) == -1) {			errorn("FE_READ_STATUS failed");			return -1;		}		verbose(">>> tuning status == 0x%02x\n", s);		if (s & FE_HAS_LOCK) {			t->last_tuning_failed = 0;			return 0;		}	}	warning(">>> tuning failed!!!\n");	t->last_tuning_failed = 1;	return -1;}static int tune_to_transponder (int frontend_fd, struct transponder *t){	/* move TP from "new" to "scanned" list */	list_del_init(&t->list);	list_add_tail(&t->list, &scanned_transponders);	t->scan_done = 1;	if (t->type != fe_info.type) {		warning("frontend type (%s) is not compatible with requested tuning type (%s)\n",				fe_type2str(fe_info.type),fe_type2str(t->type));		/* ignore cable descriptors in sat NIT and vice versa */		t->last_tuning_failed = 1;		return -1;	}	if (__tune_to_transponder (frontend_fd, t) == 0)		return 0;	return __tune_to_transponder (frontend_fd, t);}static int tune_to_next_transponder (int frontend_fd){	struct list_head *pos, *tmp;	struct transponder *t, *to;	uint32_t freq;	list_for_each_safe(pos, tmp, &new_transponders) {		t = list_entry (pos, struct transponder, list);retry:		if (tune_to_transponder (frontend_fd, t) == 0)			return 0;next:		if (t->other_frequency_flag && t->other_f && t->n_other_f) {			/* check if the alternate freqeuncy is really new to us */			freq = t->other_f[t->n_other_f - 1];			t->n_other_f--;			if (find_transponder(freq))				goto next;			/* remember tuning to the old frequency failed */			to = calloc(1, sizeof(*to));			to->param.frequency = t->param.frequency;			to->wrong_frequency = 1;			INIT_LIST_HEAD(&to->list);			INIT_LIST_HEAD(&to->services);			list_add_tail(&to->list, &scanned_transponders);			copy_transponder(to, t);			t->param.frequency = freq;			info("retrying with f=%d\n", t->param.frequency);			goto retry;		}	}	return -1;}struct strtab {	const char *str;	int val;};static int str2enum(const char *str, const struct strtab *tab, int deflt){	while (tab->str) {		if (!strcmp(tab->str, str))			return tab->val;		tab++;	}	error("invalid enum value '%s'\n", str);	return deflt;}static const char * enum2str(int v, const struct strtab *tab, const char *deflt){	while (tab->str) {		if (v == tab->val)			return tab->str;		tab++;	}	error("invalid enum value '%d'\n", v);	return deflt;}static enum fe_code_rate str2fec(const char *fec){	struct strtab fectab[] = {		{ "NONE", FEC_NONE },		{ "1/2",  FEC_1_2 },		{ "2/3",  FEC_2_3 },		{ "3/4",  FEC_3_4 },		{ "4/5",  FEC_4_5 },		{ "5/6",  FEC_5_6 },		{ "6/7",  FEC_6_7 },		{ "7/8",  FEC_7_8 },		{ "8/9",  FEC_8_9 },		{ "AUTO", FEC_AUTO },		{ NULL, 0 }	};	return str2enum(fec, fectab, FEC_AUTO);}static enum fe_modulation str2qam(const char *qam){	struct strtab qamtab[] = {		{ "QPSK",   QPSK },		{ "QAM16",  QAM_16 },		{ "QAM32",  QAM_32 },		{ "QAM64",  QAM_64 },		{ "QAM128", QAM_128 },		{ "QAM256", QAM_256 },		{ "AUTO",   QAM_AUTO },		{ "8VSB",   VSB_8 },		{ "16VSB",  VSB_16 },		{ NULL, 0 }	};	return str2enum(qam, qamtab, QAM_AUTO);}static enum fe_bandwidth str2bandwidth(const char *bw){	struct strtab bwtab[] = {		{ "8MHz", BANDWIDTH_8_MHZ },		{ "7MHz", BANDWIDTH_7_MHZ },		{ "6MHz", BANDWIDTH_6_MHZ },		{ "AUTO", BANDWIDTH_AUTO },		{ NULL, 0 }	};	return str2enum(bw, bwtab, BANDWIDTH_AUTO);}static enum fe_transmit_mode str2mode(const char *mode){	struct strtab modetab[] = {		{ "2k",   TRANSMISSION_MODE_2K },		{ "8k",   TRANSMISSION_MODE_8K },		{ "AUTO", TRANSMISSION_MODE_AUTO },		{ NULL, 0 }	};	return str2enum(mode, modetab, TRANSMISSION_MODE_AUTO);}static enum fe_guard_interval str2guard(const char *guard){	struct strtab guardtab[] = {		{ "1/32", GUARD_INTERVAL_1_32 },		{ "1/16", GUARD_INTERVAL_1_16 },		{ "1/8",  GUARD_INTERVAL_1_8 },		{ "1/4",  GUARD_INTERVAL_1_4 },		{ "AUTO", GUARD_INTERVAL_AUTO },		{ NULL, 0 }	};	return str2enum(guard, guardtab, GUARD_INTERVAL_AUTO);}static enum fe_hierarchy str2hier(const char *hier){	struct strtab hiertab[] = {		{ "NONE", HIERARCHY_NONE },		{ "1",    HIERARCHY_1 },		{ "2",    HIERARCHY_2 },		{ "4",    HIERARCHY_4 },		{ "AUTO", HIERARCHY_AUTO },		{ NULL, 0 }	};	return str2enum(hier, hiertab, HIERARCHY_AUTO);}static const char * fe_type2str(fe_type_t t){	struct strtab typetab[] = {		{ "QPSK", FE_QPSK,},		{ "QAM",  FE_QAM, },		{ "OFDM", FE_OFDM,},		{ "ATSC", FE_ATSC,},		{ NULL, 0 }	};	return enum2str(t, typetab, "UNK");}static int tune_initial (int frontend_fd, const char *initial){	FILE *inif;	unsigned int f, sr;	char buf[200];	char pol[20], fec[20], qam[20], bw[20], fec2[20], mode[20], guard[20], hier[20];	struct transponder *t;	inif = fopen(initial, "r");	if (!inif) {		error("cannot open '%s': %d %m\n", initial, errno);		return -1;	}	while (fgets(buf, sizeof(buf), inif)) {		if (buf[0] == '#' || buf[0] == '\n')			;		else if (sscanf(buf, "S %u %1[HVLR] %u %4s\n", &f, pol, &sr, fec) == 4) {			t = alloc_transponder(f);			t->type = FE_QPSK;			switch(pol[0]) {				case 'H':				case 'L':					t->polarisation = POLARISATION_HORIZONTAL;					break;				default:					t->polarisation = POLARISATION_VERTICAL;;					break;			}			t->param.inversion = spectral_inversion;			t->param.u.qpsk.symbol_rate = sr;			t->param.u.qpsk.fec_inner = str2fec(fec);			info("initial transponder %u %c %u %d\n",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -