static void process_pat(int pat_fd, struct gnutv_dvb_params *params, int *pmt_fd, struct pollfd *pollfd)
{
	int size;
	uint8_t sibuf[4096];

	// read the section
	if ((size = read(pat_fd, sibuf, sizeof(sibuf))) < 0) {
		return;
	}

	// parse section
	struct section *section = section_codec(sibuf, size);
	if (section == NULL) {
		return;
	}

	// parse section_ext
	struct section_ext *section_ext = section_ext_decode(section, 0);
	if (section_ext == NULL) {
		return;
	}
	if (pat_version == section_ext->version_number) {
		return;
	}

	// parse PAT
	struct mpeg_pat_section *pat = mpeg_pat_section_codec(section_ext);
	if (pat == NULL) {
		return;
	}

	// try and find the requested program
	struct mpeg_pat_program *cur_program;
	mpeg_pat_section_programs_for_each(pat, cur_program) {
		if (cur_program->program_number == params->channel.service_id) {
			// close old PMT fd
			if (*pmt_fd != -1)
				close(*pmt_fd);

			// create PMT filter
			if ((*pmt_fd = create_section_filter(params->adapter_id, params->demux_id,
							     cur_program->pid, stag_mpeg_program_map)) < 0) {
				return;
			}
			pollfd->fd = *pmt_fd;
			pollfd->events = POLLIN|POLLPRI|POLLERR;

			gnutv_data_new_pat(cur_program->pid);

			// we have a new PMT pid
			data_pmt_version = -1;
			ca_pmt_version = -1;
			break;
		}
	}

	// remember the PAT version
	pat_version = section_ext->version_number;
}
Esempio n. 2
0
void parse_events(uint8_t *buf, int len, list<event_data> &events)
{
    struct section *section;
    struct section_ext *section_ext = NULL;

    if ((section = section_codec(buf, len)) == NULL) {
        return;
    }

    switch(section->table_id) {

    case stag_dvb_event_information_nownext_actual:
    case stag_dvb_event_information_nownext_other:
    case 0x50: case 0x51: case 0x52: case 0x53: case 0x54: case 0x55: case 0x56: case 0x57:
    case 0x58: case 0x59: case 0x5a: case 0x5b: case 0x5c: case 0x5d: case 0x5e: case 0x5f:
    case 0x60: case 0x61: case 0x62: case 0x63: case 0x64: case 0x65: case 0x66: case 0x67:
    case 0x68: case 0x69: case 0x6a: case 0x6b: case 0x6c: case 0x6d: case 0x6e: case 0x6f:
    {

        struct dvb_eit_section *eit;
        struct dvb_eit_event *cur_event;
        struct descriptor *curd;
        time_t start_time;

        if ((section_ext = section_ext_decode(section, 1)) == NULL) {
            return;
        }

        if ((eit = dvb_eit_section_codec(section_ext)) == NULL) {
            return;
        }

        dvb_eit_section_events_for_each(eit, cur_event) {

            event_data E = event_data();


            start_time = dvbdate_to_unixtime(cur_event->start_time);

            E.set_service_id(dvb_eit_section_service_id(eit));
            E.set_event_id(cur_event->event_id);
            E.set_duration(dvbduration_to_seconds(cur_event->duration));
            E.set_running_status(cur_event->running_status);
            E.set_start_time((int) start_time);

            dvb_eit_event_descriptors_for_each(cur_event, curd) {
                parse_event_descriptor(curd,  E);
            }

            AddIntoEventList(events, E);

        }
        break;
    }
static void process_pmt(int pmt_fd, struct gnutv_dvb_params *params)
{
	int size;
	uint8_t sibuf[4096];

	// read the section
	if ((size = read(pmt_fd, sibuf, sizeof(sibuf))) < 0) {
		return;
	}

	// parse section
	struct section *section = section_codec(sibuf, size);
	if (section == NULL) {
		return;
	}

	// parse section_ext
	struct section_ext *section_ext = section_ext_decode(section, 0);
	if (section_ext == NULL) {
		return;
	}
	if ((section_ext->table_id_ext != params->channel.service_id) ||
	    ((section_ext->version_number == data_pmt_version) &&
	     (section_ext->version_number == ca_pmt_version))) {
		return;
	}

	// parse PMT
	struct mpeg_pmt_section *pmt = mpeg_pmt_section_codec(section_ext);
	if (pmt == NULL) {
		return;
	}

	// do data handling
	if (section_ext->version_number != data_pmt_version) {
		if (gnutv_data_new_pmt(pmt) == 1)
			data_pmt_version = pmt->head.version_number;
	}

	// do ca handling
	if (section_ext->version_number != ca_pmt_version) {
		if (gnutv_ca_new_pmt(pmt) == 1)
			ca_pmt_version = pmt->head.version_number;
	}
}
Esempio n. 4
0
/*
 * Get the next date packet from the STT section
 */
int atsc_scan_date(time_t *rx_time, unsigned int to)
{
	int stt_fd;
	uint8_t filter[18];
	uint8_t mask[18];
	unsigned char sibuf[4096];
	int size;

	// open the demuxer
	if ((stt_fd = dvbdemux_open_demux(adapter, 0, 0)) < 0) {
		return -1;
	}

	// create a section filter for the STT
	memset(filter, 0, sizeof(filter));
	memset(mask, 0, sizeof(mask));
	filter[0] = stag_atsc_system_time;
	mask[0] = 0xFF;
	if (dvbdemux_set_section_filter(stt_fd, ATSC_BASE_PID, filter, mask, 1, 1)) {
		close(stt_fd);
		return -1;
	}

	// poll for data
	struct pollfd pollfd;
	pollfd.fd = stt_fd;
	pollfd.events = POLLIN|POLLERR|POLLPRI;
	if (poll(&pollfd, 1, to * 1000) != 1) {
		close(stt_fd);
		return -1;
	}

	// read it
	if ((size = read(stt_fd, sibuf, sizeof(sibuf))) < 0) {
		close(stt_fd);
		return -1;
	}

	// parse section
	struct section *section = section_codec(sibuf, size);
	if (section == NULL) {
		close(stt_fd);
		return -1;
	}
	struct section_ext *section_ext = section_ext_decode(section, 0);
	if (section_ext == NULL) {
		close(stt_fd);
		return -1;
	}
	struct atsc_section_psip *psip = atsc_section_psip_decode(section_ext);
	if (psip == NULL) {
		close(stt_fd);
		return -1;
	}

	// parse STT
	struct atsc_stt_section *stt = atsc_stt_section_codec(psip);
	if (stt == NULL) {
		close(stt_fd);
		return -1;
	}

	// done
	*rx_time = atsctime_to_unixtime(stt->system_time);
	close(stt_fd);
	return 0;
}
Esempio n. 5
0
static void
linuxdvb_ca_process_capmt_queue ( void *aux )
{
  linuxdvb_ca_t *lca = aux;
  linuxdvb_ca_capmt_t *lcc;
  struct section *section;
  struct section_ext *result;
  struct mpeg_pmt_section *pmt;
  uint8_t capmt[4096];
  int size, i;

  lcc = TAILQ_FIRST(&lca->lca_capmt_queue);

  if (!lcc)
    return;

  if (!(section = section_codec(lcc->data, lcc->len))){
    tvherror("en50221", "failed to decode PMT section");
    goto done;
  }

  if (!(result = section_ext_decode(section, 0))){
    tvherror("en50221", "failed to decode PMT ext_section");
    goto done;
  }

  if (!(pmt = mpeg_pmt_section_codec(result))){
    tvherror("en50221", "failed to decode PMT");
    goto done;
  }

  size = en50221_ca_format_pmt(pmt, capmt, sizeof(capmt), 0,
                               lcc->list_mgmt, lcc->cmd_id);

  if (size < 0) {
    tvherror("en50221", "Failed to format CAPMT");
  }

  if (en50221_app_ca_pmt(lca->lca_ca_resource, lca->lca_ca_session_number,
                         capmt, size)) {
        tvherror("en50221", "Failed to send CAPMT");
  }

  tvhtrace("en50221", "%s CAPMT sent (%s)", ca_pmt_cmd_id2str(lcc->cmd_id),
           ca_pmt_list_mgmt2str(lcc->list_mgmt));
  tvhlog_hexdump("en50221", capmt, size);

done:
  i = (lcc->cmd_id == CA_PMT_CMD_ID_QUERY) ?
    lca->lca_capmt_query_interval : lca->lca_capmt_interval;

  TAILQ_REMOVE(&lca->lca_capmt_queue, lcc, lcc_link);

  free(lcc->data);
  free(lcc);

  if (!TAILQ_EMPTY(&lca->lca_capmt_queue)) {
    gtimer_arm_ms(&lca->lca_capmt_queue_timer,
                  linuxdvb_ca_process_capmt_queue, lca, i);
  }
}