void xmux_config_save_pid_map_table(struct xmux_pid_map_table *t) { trace_info("save pid map table..."); if (!pid_map_table_validate(t)) { trace_err("pid map table invalidate! save nothing!"); return; } pid_map_table_dump(t); g_eeprom_param.pid_map_table_area.pid_map_table = *t; eeprom_write(EEPROM_OFF_PID_MAP_TABLE, t, sizeof(*t)); }
int front_panel_open() { fd = openport(fp_tty, B115200); if (fd <= 0) { trace_err("failed to open port!"); return -1; } wu_swait_init(&fp_swait); trace_info("success open front panel port"); return 0; }
void pid_map_table_gen_and_apply_from_fp() { struct pid_map_table_gen_context gen_ctx; int chan_idx, prog_idx; uint16_t in_pid; /* clear mux program info */ memset(&g_eeprom_param.mux_prog_info, 0, sizeof(struct xmux_mux_program_info)); pid_map_table_gen_start(&gen_ctx); /* * gather pid map from io_table */ build_io_table(); for (chan_idx = 0; chan_idx < CHANNEL_MAX_NUM; chan_idx++) { for (in_pid = 0x20; in_pid < NULL_PID; in_pid++) { if (!(io_table[chan_idx][in_pid].flags & IO_PID_FLAG_SELECTED)) continue; #if CHANNEL_MAX_NUM == 1 /* FIXME: should we set the output pid to NULL_PID? */ if (!(io_table[chan_idx][in_pid].flags & IO_PID_FLAG_PMT_PID)) #else if (io_table[chan_idx][in_pid].flags & IO_PID_FLAG_PMT_PID) #endif continue; if (pid_map_table_push_pid_pair(&gen_ctx, chan_idx, in_pid, io_table[chan_idx][in_pid].out_pid)) { trace_err("channel #%d pid exceed! discard pid %#x => %#", chan_idx, in_pid, io_table[chan_idx][in_pid].out_pid); } } } /* fill mux program info */ for (chan_idx = 0; chan_idx < CHANNEL_MAX_NUM; chan_idx++) { for (prog_idx = 0; prog_idx < g_chan_num.num[chan_idx]; prog_idx++) { PROG_INFO_T *prog = &g_prog_info_table[chan_idx * PROGRAM_MAX_NUM + prog_idx]; if (FP_PROG_SELECTED(prog)) { g_eeprom_param.mux_prog_info.programs[g_eeprom_param.mux_prog_info.nprogs].chan_idx = chan_idx; g_eeprom_param.mux_prog_info.programs[g_eeprom_param.mux_prog_info.nprogs].prog_idx = prog_idx; g_eeprom_param.mux_prog_info.nprogs++; } } } pid_map_gen_done: pid_map_table_gen_end(&gen_ctx, CHANNEL_ALL_BITMAP); xmux_config_save_pid_map_table(gen_ctx.fpga_pid_map.pid_map); hfpga_write_pid_map(&gen_ctx.fpga_pid_map); }
int front_panel_run() { if (fd <= 0) { trace_err("port not opened! disable front panel!"); return -1; } fp_thr = thread_create(fp_thread, NULL); if (!fp_thr) { return -1; } return 0; }
static void eeprom_rw_test() { uint8_t data[1024], read_data[1024]; int i; trace_info("eeprom test..."); for (i = 0; i < 1024; i++) data[i] = i; eeprom_write(0, data, 1024); eeprom_read(0, read_data, 1024); for (i = 0; i < 1024; i++) { if (read_data[i] != data[i]) { trace_err("#%d write %#x, read %#x", i, data[i], read_data[i]); } } }
struct fp_cmd * front_panel_send_cmd(struct fp_cmd *cmd, int expect_cmd) { int rc; struct fp_cmd *resp_cmd = NULL; if (wu_swait_is_alive(&fp_swait)) { trace_warn("busy! ignore this send cmd request!"); return NULL; } rc = write(fd, cmd, FP_CMD_SIZE(cmd)); if (rc < FP_CMD_SIZE(cmd)) { trace_err("wirte cmd failed!"); return NULL; } fp_expect_cmd = expect_cmd; resp_cmd = wu_swait_timedwait(&fp_swait, 2000000); fp_expect_cmd = -1; return resp_cmd; }
void xmux_config_save_pid_trans_info_all() { uint8_t chan_idx; struct pid_trans_info_snmp_data *info; uint32_t off; trace_info("save pid trans info..."); for (chan_idx = 0; chan_idx < CHANNEL_MAX_NUM; chan_idx++) { info = &g_eeprom_param.pid_trans_info_area.table[chan_idx].data; if (!pid_trans_info_validate(info)) { trace_err("#%d pid trans info invalidate!", chan_idx); continue; } pid_trans_info_dump(chan_idx, info); off = EEPROM_OFF_PID_TRANS_INFO + sizeof(g_eeprom_param.pid_trans_info_area.table[0]) * chan_idx; trace_info("#%d pid trans info eeprom offset %#x", chan_idx, off); eeprom_write(off, info, info->data_len + 2); usleep(100000); } }
/* * @return: 1 the @cmd is response cmd */ int front_panel_check_recv_cmd(struct fp_cmd *recv_cmd) { int cmd = SWAP_U16(recv_cmd->header.seq) & 0x7FFF; int is_read = SWAP_U16(recv_cmd->header.seq) & 0x8000; bool check_enter_fp = true; /* * check force enter to fp management mode */ if (cmd == FP_CMD_SYS) { uint16_t sys_cmd = READ_U16_BE(recv_cmd->data); if (sys_cmd == FP_SYS_CMD_READ_TS_STATUS || sys_cmd == FP_SYS_CMD_ENTER_FP_MANAGEMENT_MODE || sys_cmd == FP_SYS_CMD_LEAVE_FP_MANAGEMENT_MODE) { check_enter_fp = false; } } else if (cmd == FP_CMD_OUT_RATE && is_read) { check_enter_fp = false; } if (check_enter_fp && (management_mode != MANAGEMENT_MODE_FP)) { trace_warn("recv cmd in none fp mode! force switch!"); enter_fp_management_mode(); } if (cmd == fp_expect_cmd) { static char buf[1024]; struct fp_cmd *resp_cmd = (struct fp_cmd *)buf; fp_cmd_copy(resp_cmd, recv_cmd); if (wu_swait_wakeup(&fp_swait, resp_cmd)) { trace_err("recv respone cmd %d, but maybe had timeouted!", cmd); } return 1; } return 0; }
static bool xmux_eeprom_param_validate(struct xmux_eeprom_param *p) { struct pid_trans_info_snmp_data *pid_trans_info; uint8_t chan_idx; /* * management mode */ management_mode = MANAGEMENT_MODE_SNMP; /* * pid trans info */ for (chan_idx = 0; chan_idx < CHANNEL_MAX_NUM; chan_idx++) { pid_trans_info = &p->pid_trans_info_area.table[chan_idx].data; if (!pid_trans_info_validate(pid_trans_info)) { trace_err("#%d pid trans info invalidate!", chan_idx); memset(pid_trans_info, 0, sizeof(struct pid_trans_info_snmp_data)); continue; } pid_trans_info_dump(chan_idx, pid_trans_info); } /* * pid map table */ if (pid_map_table_validate(&p->pid_map_table_area.pid_map_table)) { pid_map_table_dump(&p->pid_map_table_area.pid_map_table); } else { trace_err("pid map table invalidate!"); pid_map_table_clear(&p->pid_map_table_area.pid_map_table); } /* * output psi */ if (output_psi_data_validate(&p->output_psi_area.output_psi)) { output_psi_data_dump(&p->output_psi_area.output_psi); } else { trace_err("output psi data invalidate!"); output_psi_data_clear(&p->output_psi_area.output_psi); } #if CHANNEL_MAX_NUM == 1 memcpy(g_input_pmt_sec, g_eeprom_param.input_pmt_sec, sizeof(g_input_pmt_sec)); #endif /* * sys */ if (xmux_system_param_validate(&p->sys)) { xmux_system_param_dump(&p->sys); } else { trace_err("system param invalidate!"); hex_dump("sys", &p->sys, sizeof(p->sys)); xmux_system_param_init_default(&p->sys); } /* * net */ if (xmux_net_param_validate(&p->net)) { xmux_net_param_dump(&p->net); } else { trace_err("net param invalidate!"); xmux_net_param_init_default(&p->net); eeprom_write(EEPROM_OFF_NET, &p->net, sizeof(p->net)); } /* * user */ if (xmux_user_param_validate(&p->user)) { xmux_user_param_dump(&p->user); } else { trace_err("user param invalidate!"); xmux_user_param_init_default(&p->user); } return true; }
/* * if load failed then fallback to default */ void xmux_config_load_from_eeprom() { uint8_t chan_idx; /* * load real data, so accelerate load speed */ eeprom_read(EEPROM_OFF_MISC_PARAM, (uint8_t *)&g_eeprom_param.sys, EEPROM_MISC_PARAM_SIZE); /* pid_trans_info_area */ // read head for (chan_idx = 0; chan_idx < CHANNEL_MAX_NUM; chan_idx++) { struct pid_trans_info_snmp_data *info; uint16_t data_len = 0; uint32_t off = EEPROM_OFF_PID_TRANS_INFO + sizeof(struct eeprom_pid_trans_info) * chan_idx; info = &g_eeprom_param.pid_trans_info_area.table[chan_idx].data; eeprom_read(off, (uint8_t *)&data_len, 2); trace_info("channel #%d pid trans info data_len %d, off %#x", chan_idx, data_len, off); eeprom_read(off, (uint8_t *)info, MIN(data_len + 2, sizeof(struct pid_trans_info_snmp_data))); } eeprom_read(EEPROM_OFF_PID_MAP_TABLE, (uint8_t *)&g_eeprom_param.pid_map_table_area, sizeof(g_eeprom_param.pid_map_table_area)); /* output_psi_area */ // read head eeprom_read(EEPROM_OFF_OUTPUT_PSI, (uint8_t *)&g_eeprom_param.output_psi_area, sizeof(g_eeprom_param.output_psi_area.output_psi)); trace_info("output_psi had %d packages", g_eeprom_param.output_psi_area.output_psi.pkt_nr); // read all eeprom_read(EEPROM_OFF_OUTPUT_PSI, (uint8_t *)&g_eeprom_param.output_psi_area, MIN(sizeof(g_eeprom_param.output_psi_area), sizeof(g_eeprom_param.output_psi_area.output_psi) + g_eeprom_param.output_psi_area.output_psi.pkt_nr * TS_PACKET_BYTES)); #if CHANNEL_MAX_NUM == 1 eeprom_read(EEPROM_OFF_INPUT_PMT_SEC, (uint8_t *)g_eeprom_param.input_pmt_sec, sizeof(g_eeprom_param.input_pmt_sec)); eeprom_read(EEPROM_OFF_TUNNER, (uint8_t *)g_eeprom_param.tunner, sizeof(g_eeprom_param.tunner)); #endif /* * force to snmp management mode always in startup! else if we are starting * and in fp management mode, if the fp is malfunction, then out of control! */ g_eeprom_param.misc.mng_mode = MANAGEMENT_MODE_SNMP; /* checkint */ if (!xmux_eeprom_param_validate(&g_eeprom_param)) { trace_err("invalidate xmux root param load from eeprom, fallback to default!"); xmux_eeprom_param_init_default(&g_eeprom_param); } else { trace_info("xmux root param success load from eeprom"); } g_param_mng_info.eeprom_pid_trans_info_version++; g_param_mng_info.eeprom_pid_map_table_version++; }
// this function executes server-side commands only // must be called only from within server // -1 error, program must exit with error code -1 // 0 proceed normally as nothing happened // 1 no error, but program must exit with error code 0 // 2 don't load playlist on startup // when executed in remote server -- error code will be ignored int server_exec_command_line (const char *cmdline, int len, char *sendback, int sbsize) { if (sendback) { sendback[0] = 0; } const char *parg = cmdline; const char *pend = cmdline + len; int queue = 0; while (parg < pend) { if (strlen (parg) >= 2 && parg[0] == '-' && parg[1] != '-') { parg += strlen (parg); parg++; return 0; // running under osx debugger? } else if (!strcmp (parg, "--nowplaying")) { parg += strlen (parg); parg++; if (parg >= pend) { const char *errtext = "--nowplaying expects format argument"; if (sendback) { snprintf (sendback, sbsize, "error %s\n", errtext); return 0; } else { trace_err ("%s\n", errtext); return -1; } } char out[2048]; playItem_t *curr = streamer_get_playing_track (); if (curr) { pl_format_title (curr, -1, out, sizeof (out), -1, parg); pl_item_unref (curr); } else { strcpy (out, "nothing"); } if (sendback) { snprintf (sendback, sbsize, "nowplaying %s", out); } else { fwrite (out, 1, strlen (out), stdout); return 1; // exit } } else if (!strcmp (parg, "--nowplaying-tf")) { parg += strlen (parg); parg++; if (parg >= pend) { const char *errtext = "--nowplaying-tf expects format argument"; if (sendback) { snprintf (sendback, sbsize, "error %s\n", errtext); return 0; } else { trace_err ("%s\n", errtext); return -1; } } char out[2048]; playItem_t *curr = streamer_get_playing_track (); char *script = tf_compile (parg); if (script) { ddb_tf_context_t ctx = { ._size = sizeof (ddb_tf_context_t), .it = (DB_playItem_t *)curr, }; tf_eval (&ctx, script, out, sizeof (out)); tf_free (script); } else { *out = 0; } if (curr) { pl_item_unref (curr); } if (sendback) { snprintf (sendback, sbsize, "nowplaying %s", out); } else { fwrite (out, 1, strlen (out), stdout); return 1; // exit } } else if (!strcmp (parg, "--next")) {
int main(int argc, char **argv) { int socklen; struct evconnlistener *listener; if (argc < 2) { syntax(); } adapter = ssh_adapter_new(); if(adapter == NULL) { trace_err("ssh_adapter create failed."); return 0x01; } //ssh_adapter_options_set(adapter, SSH_BIND_OPTIONS_HOSTKEY, xKEYS_FOLDER "ssh_host_key"); ssh_adapter_options_set(adapter, SSH_BIND_OPTIONS_DSAKEY, xKEYS_FOLDER "ssh_host_dsa_key"); ssh_adapter_options_set(adapter, SSH_BIND_OPTIONS_RSAKEY, xKEYS_FOLDER "ssh_host_rsa_key"); ssh_adapter_options_set(adapter, SSH_BIND_OPTIONS_LOG_VERBOSITY_STR, "4"); ssh_adapter_init(adapter); memset(&listen_on_addr, 0, sizeof(listen_on_addr)); socklen = sizeof(listen_on_addr); if (evutil_parse_sockaddr_port(argv[1], (struct sockaddr*)&listen_on_addr, &socklen)<0) { int p = atoi(argv[1]); struct sockaddr_in *sin = (struct sockaddr_in*)&listen_on_addr; if (p < 1 || p > 65535) { syntax(); } sin->sin_port = htons(p); sin->sin_addr.s_addr = htonl(0x7f000001); sin->sin_family = AF_INET; socklen = sizeof(struct sockaddr_in); } memset(&connect_to_addr, 0, sizeof(connect_to_addr)); connect_to_addrlen = sizeof(connect_to_addr); if (evutil_parse_sockaddr_port(argv[2], (struct sockaddr*)&connect_to_addr, &connect_to_addrlen)<0) { syntax(); } base = event_base_new(); if (!base) { perror("event_base_new()"); return 1; } listener = evconnlistener_new_bind(base, accept_cb, NULL, LEV_OPT_CLOSE_ON_FREE|LEV_OPT_CLOSE_ON_EXEC|LEV_OPT_REUSEABLE, -1, (struct sockaddr*)&listen_on_addr, socklen); if (!listener) { fprintf(stderr, "Couldn't open listener.\n"); event_base_free(base); return 1; } event_base_dispatch(base); evconnlistener_free(listener); event_base_free(base); return 0; }
static void accept_cb(struct evconnlistener *listener, evutil_socket_t fd, struct sockaddr *sa, int slen, void *p) { ssh_session_t *session_in = NULL, *session_out = NULL; struct bufferevent *b_out, *b_in; // Create two linked bufferevent objects: one to connect, one for the new connection b_in = bufferevent_socket_new(base, fd, BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); b_out = bufferevent_socket_new(base, -1, BEV_OPT_CLOSE_ON_FREE|BEV_OPT_DEFER_CALLBACKS); do_assert(b_in && b_out); if (bufferevent_socket_connect(b_out, (struct sockaddr*)&connect_to_addr, connect_to_addrlen)<0) { perror("bufferevent_socket_connect"); bufferevent_free(b_out); bufferevent_free(b_in); return; } // client session_in = ssh_new(); // server session_out = ssh_new(); session_in->proxy = 1; session_in->type = SSH_SESSION_CLIENT; session_in->owner_ptr = b_out; api_name_from_addr(sa, slen, &(session_in->cip),&(session_in->cport)); api_name_from_addr((struct sockaddr *)&connect_to_addr, connect_to_addrlen, &(session_in->sip),&(session_in->sport)); ssh_adapter_accept(adapter, session_in); session_in->session_ptr = session_out; session_in->evbuffer = bufferevent_get_output(b_in); session_in->data_send = session_data_send; //session_callback_init(session_in); ssh_handle_key_exchange(session_in); bufferevent_setcb(b_in, data_read_handler, data_write_handler, event_error_handler, session_in); session_out->proxy = 1; session_out->session_state = SSH_SESSION_STATE_SOCKET_CONNECTED; session_out->type = SSH_SESSION_SERVER; session_out->owner_ptr = b_in; api_name_from_addr(sa, slen, &(session_out->cip),&(session_out->cport)); api_name_from_addr((struct sockaddr*)&connect_to_addr, connect_to_addrlen, &(session_out->sip),&(session_out->sport)); //ssh_adapter_accept(adapter, session_out); session_out->session_ptr = session_in; session_out->evbuffer = bufferevent_get_output(b_out); session_out->data_send = session_data_send; //session_callback_init(session_out); { int ret = ssh_connect(session_out); if(ret != SSH_OK) { trace_err("init proxy-client failed."); } /* ret = knownhost_verify(session_out); if(ret != SSH_OK) { trace_err("iknownhost_verify failed."); }*/ } ssh_log(session_in, "accept a new session: [%s:%d] -> [%s:%d]", session_in->cip, session_in->cport, session_in->sip, session_in->sport); bufferevent_setcb(b_out, data_read_handler, data_write_handler, event_error_handler, session_out); bufferevent_enable(b_in, EV_READ|EV_WRITE); bufferevent_enable(b_out, EV_READ|EV_WRITE); }
int psi_apply_from_output_psi() { struct xmux_output_psi_data *psi_data = &g_eeprom_param.output_psi_area.output_psi; struct output_psi_data_entry *ent; uint8_t psi_type, howto = 0; int i; struct psisi_write_info write_info[PSISI_MAX_NUM] = {0}; int mul_pkt_off = PSISI_MUL_PKT_0 - 1; /* * create packet temp buffer */ for (i = 0; i < PSISI_MAX_NUM; i++) { write_info[i].pkts_buf = malloc(TS_PACKET_BYTES * 128); if (!write_info[i].pkts_buf) { trace_err("can't allocate pkts_buf!"); return -1; } } trace_info("apply psi to fpga..."); dvbSI_Start(&hfpga_dev); dvbSI_GenSS(HFPGA_CMD_SI_STOP); for (psi_type = 0; psi_type < OUTPUT_PSI_TYPE_MAX_NUM; psi_type++) { ent = &psi_data->psi_ents[psi_type]; if (ent->nr_ts_pkts) { howto = psi_type_2_howto(psi_type); trace_info("write type %d, offset %d, %d packets", psi_type, ent->offset, ent->nr_ts_pkts); for (i = 0; i < ent->nr_ts_pkts; i++) { hex_dump("ts", &psi_data->ts_pkts[ent->offset] + i, 48); } /* * handle multiple same pid of PISSI_40MS type pid */ if (howto == PSISI_40MS) { uint8_t *ts; uint16_t last_pid = 0xFFFF, pid, next_pid; for (i = 0; i < ent->nr_ts_pkts; i++) { ts = (uint8_t *)(&psi_data->ts_pkts[ent->offset] + i); pid = GET_PID(ts); next_pid = (i == (ent->nr_ts_pkts - 1)) ? 0xFFFF: GET_PID(ts + 188); if (pid == last_pid || pid == next_pid) { if (pid != last_pid) { mul_pkt_off++; } if (mul_pkt_off <= PSISI_MUL_PKT_3) { howto = mul_pkt_off; trace_info("%#x [%#x] %#x, put to %x", last_pid, pid, next_pid, mul_pkt_off); } else { howto = PSISI_40MS; } } else { howto = PSISI_40MS; } memcpy(write_info[howto].pkts_buf + write_info[howto].size, ts, 188); write_info[howto].size += 188; last_pid = pid; } continue; } memcpy(write_info[howto].pkts_buf + write_info[howto].size, &psi_data->ts_pkts[ent->offset], 188 * ent->nr_ts_pkts); write_info[howto].size += 188 * ent->nr_ts_pkts; } } trace_info("do write to fpga ..."); /* * write to fpga */ disable_snmp_connection_check(); for (i = 0; i < PSISI_MAX_NUM; i++) { if (write_info[i].size <= 0) continue; howto = i; trace_info("write #%d, size %d, howto %d to fpga ...", i, write_info[i].size, howto); hfpga_dev.write(write_info[i].pkts_buf, write_info[i].size, &howto); free(write_info[i].pkts_buf); } enable_snmp_connection_check(); trace_info("readback psi ..."); dvb_io_dev.ioctl(0x11, NULL); // readback psi from fpga and dump it dvbSI_GenSS(HFPGA_CMD_SI_START); dvbSI_Stop(&hfpga_dev); trace_info("apply psi to fpga done."); return 0; }
static int fp_thread(void *data) { int rc; fd_set rset; struct timeval tv; int readed_len = 0; uint8_t recv_buf[FP_RECV_MSG_MAX_SIZE + 10]; trace_info("front panel thread running ..."); while (!fp_thread_quit) { FD_ZERO(&rset); FD_SET(fd, &rset); tv.tv_sec = 1; tv.tv_usec = 0; rc = select(fd + 1, &rset, NULL, NULL, &tv); if (rc <= 0) { readed_len = 0; continue; } else if (FD_ISSET(fd, &rset)) { int nlen = 0; struct fp_cmd_header hdr; // read header nlen = read(fd, recv_buf + readed_len, sizeof(hdr) - readed_len); if (nlen < 0) { trace_err("failed to read header, readed %d!", readed_len); readed_len = 0; continue; } else { readed_len += nlen; if (readed_len == sizeof(struct fp_cmd_header)) { // got readed_len = 0; } else { continue; } } if (recv_buf[0] != defMcuSyncFlag) { trace_err("invalid sync byte %#x! flush buffer..", recv_buf[0]); hex_dump("invalid header", recv_buf, sizeof(hdr)); nlen = read(fd, recv_buf, FP_RECV_MSG_MAX_SIZE); if (nlen > 0) { trace_err("discard %d bytes data...", nlen); hex_dump("discard data", recv_buf, MIN(nlen, 16)); } continue; } buf_2_fp_cmd_header(&hdr, recv_buf); if (hdr.len + sizeof(hdr) + FP_MSG_CRC_SIZE > FP_RECV_MSG_MAX_SIZE) { trace_err("error! len %d too large!", hdr.len); hex_dump("header", recv_buf, sizeof(hdr)); continue; } // read body and crc nlen = read_bytes(recv_buf + sizeof(hdr), hdr.len + FP_MSG_CRC_SIZE); if (nlen == hdr.len + FP_MSG_CRC_SIZE) { // ok, parse the msg parse_mcu_cmd(fd, recv_buf); } } } trace_info("front panel thread quited"); return 0; }
static int do_parse_channel(PROG_INFO_T *chan_prog_info, uint8_t * p_chan_prog_cnt, uint8_t chan_idx) { int i, j, k; uint8_t prog_cnt = 0; PROG_INFO_T *prog_info; int rc = 0; uint16_t pids[PROGRAM_PID_MAX_NUM]; int nr_pids; pmt.p_descr = pmt_descr; for (i = 0; i < 5; i++) { pmt_descr[i].p_data = p_pmt_data[i]; } for (i = 0; i < PROGRAM_MAX_NUM; i++) { es[i].p_descr = es_descr[i]; stream[i].p_descr = stream_descr[i]; serv[i].p_descr = serv_descr[i]; for (j = 0; j < 5; j++) { es_descr[i][j].p_data = p_es_data[i][j]; stream_descr[i][j].p_data = p_stream_data[i][j]; serv_descr[i][j].p_data = p_serv_data[i][j]; } } hfpga_dev.cha = chan_idx; dvbSI_Start(&hfpga_dev); trace_info("decode PAT ..."); sg_si_param.tbl_type = EUV_TBL_PAT; psi_parse_timer_start(5); rc = dvbSI_Dec_PAT(&pat, pid_data, &pid_num); psi_parse_timer_stop(); if (rc) { trace_err("pat parse failed! rc %d\n", rc); goto channel_analyse_done; } trace_info("PAT decode done, TS id %#x, pmt pid num %d", pat.i_tran_stream_id, pid_num); for (i = 0; i < pid_num; i++) { trace_info(" program #%d: program number %#x, PMT %#x", i, pid_data[i].i_pg_num, pid_data[i].i_pid); } trace_info("decode PMT ..."); #if CHANNEL_MAX_NUM == 1 sg_si_param.type = EUV_BOTH; #endif sg_si_param.tbl_type = EUV_TBL_PMT; for (i = 0; i < pid_num; i++) { if (pid_data[i].i_pg_num != 0x00) { prog_info = chan_prog_info + prog_cnt; prog_cnt++; prog_info->info.pmt.in = pid_data[i].i_pid; prog_info->info.pmt.out = pid_map_rule_map_psi_pid(chan_idx, prog_cnt - 1, DSW_PID_PMT, pid_data[i].i_pid, NULL, 0); prog_info->info.prog_num = pid_data[i].i_pg_num; trace_info("decode program_number %d, PMT %#x ...", pid_data[i].i_pg_num, pid_data[i].i_pid); pmt.i_pg_num = pid_data[i].i_pg_num; pmt.i_pmt_pid = pid_data[i].i_pid; #if CHANNEL_MAX_NUM == 1 memset(g_input_pmt_sec[prog_cnt - 1], 0, 2); sg_si_param.cur_cnt = 0; sg_si_param.sec[0] = g_input_pmt_sec[prog_cnt - 1]; #endif psi_parse_timer_start(5); rc = dvbSI_Dec_PMT(&pmt, es, &es_num); psi_parse_timer_stop(); if (rc) { trace_err("pmt parse #%d failed! rc %d\n", i, rc); goto channel_analyse_done; } #if CHANNEL_MAX_NUM == 1 /* * pmt descriptors * if we found CA_Descriptor, then it's scrambled! */ for (j = 0; j < pmt.i_descr_num; j++) { trace_info("PMT desc #%d, tag %#x, len %d, data:", j, pmt.p_descr[j].i_tag, pmt.p_descr[j].i_length); if (pmt.p_descr[j].i_tag == CA_DR_TAG) { trace_info("found CA_Descriptor!"); prog_info->status |= FP_STATUS_SCRAMBLED; } } #endif /* * clip max es number */ if (es_num > PROGRAM_DATA_PID_MAX_NUM) es_num = PROGRAM_DATA_PID_MAX_NUM; /* * scan PCR and data PIDs and we'll use them do pid remap */ nr_pids = scan_program_pids(&pmt, &es, es_num, pids); prog_info->info.pcr.type = PID_TYPE_PCR; prog_info->info.pcr.in = pmt.i_pcr_pid; prog_info->info.pcr.out = pid_map_rule_map_psi_pid(chan_idx, prog_cnt - 1, DSW_PID_PCR, pmt.i_pcr_pid, pids, nr_pids); trace_info("PCR %#x, %d descrs", pmt.i_pcr_pid, pmt.i_descr_num); for (j = 0; j < pmt.i_descr_num; j++) { trace_info("desc %d, tag %#x, len %d", j, pmt.p_descr[j].i_tag, pmt.p_descr[j].i_length); hex_dump("desc", pmt.p_descr[j].p_data, pmt.p_descr[j].i_length); } for (j = 0; j < es_num; j++) { trace_info("es %d, type %#x, pid %#x", j, es[j].i_type, es[j].i_pid); prog_info->info.data[j].type = es[j].i_type; if (es[j].i_pid != pmt.i_pcr_pid) { prog_info->info.data[j].in = es[j].i_pid; prog_info->info.data[j].out = pid_map_rule_map_psi_pid(chan_idx, prog_cnt - 1, DSW_PID_VIDEO, es[j].i_pid, pids, nr_pids); } else { prog_info->info.data[j].in = es[j].i_pid; prog_info->info.data[j].out = prog_info->info.pcr.out; /* correct pcr type */ if (es_is_video(es[j].i_type)) prog_info->info.pcr.type = PID_TYPE_PCR_VIDEO; else prog_info->info.pcr.type = PID_TYPE_PCR_AUDIO; } for (k = 0; k < es[j].i_descr_num; k++) { trace_info("es descriptor %d, tag %#x, len %d", k, es[j].p_descr[k].i_tag, es[j].p_descr[k].i_length); hex_dump("desc", es[j].p_descr[k].p_data, es[j].p_descr[k].i_length); } } } } *p_chan_prog_cnt = prog_cnt; trace_info("decode SDT ..."); sg_si_param.type = EUV_DEFAULT; sg_si_param.tbl_type = EUV_TBL_SDT; psi_parse_timer_start(20); rc = parse_sdt_section_and_decode(chan_idx, &sdt, serv, &serv_num); psi_parse_timer_stop(); if (rc) { trace_err("sdt parse failed! rc %d\n", rc); goto channel_analyse_done; } trace_info("there are total %d services", serv_num); for (j = 0; j < serv_num; j++) { for (i = 0; i < prog_cnt; i++) { prog_info = chan_prog_info + i; if (serv[j].i_serv_id == prog_info->info.prog_num) { trace_info("service #%d: service_id %#x", j, serv[j].i_serv_id); extract_program_name(serv[j].p_descr->p_data, (unsigned char *)prog_info->info.prog_name); /* set default output program name same with original */ memcpy(prog_info->info.prog_name[1], prog_info->info.prog_name[0], PROGRAM_NAME_SIZE); break; } } if (i == prog_cnt) { trace_warn("service #%d: service_id %#x, no owner program!", j, serv[j].i_serv_id); } } channel_analyse_done: dvbSI_Stop(); return rc; }