static void linuxdvb_ca_class_enabled_notify ( void *p, const char *lang ) { linuxdvb_ca_t *lca = (linuxdvb_ca_t *) p; if (lca->lca_enabled) { if (lca->lca_ca_fd < 0) { lca->lca_ca_fd = tvh_open(lca->lca_ca_path, O_RDWR | O_NONBLOCK, 0); tvhtrace("linuxdvb", "opening ca%u %s (fd %d)", lca->lca_number, lca->lca_ca_path, lca->lca_ca_fd); } } else { tvhtrace("linuxdvb", "closing ca%u %s (fd %d)", lca->lca_number, lca->lca_ca_path, lca->lca_ca_fd); if (lca->lca_en50221_thread_running) { lca->lca_en50221_thread_running = 0; pthread_join(lca->lca_en50221_thread, NULL); } ioctl(lca->lca_ca_fd, CA_RESET, NULL); close(lca->lca_ca_fd); lca->lca_ca_fd = -1; idnode_notify_title_changed(&lca->lca_id, lang); } }
/* * Output packet */ static int _timeshift_read ( timeshift_t *ts, timeshift_file_t **cur_file, off_t *cur_off, int *fd, streaming_message_t **sm, int *wait ) { if (*cur_file) { /* Open file */ if (*fd == -1) { tvhtrace("timeshift", "ts %d open file %s", ts->id, (*cur_file)->path); *fd = open((*cur_file)->path, O_RDONLY); } tvhtrace("timeshift", "ts %d seek to %"PRIoff_t, ts->id, *cur_off); lseek(*fd, *cur_off, SEEK_SET); /* Read msg */ ssize_t r = _read_msg(*fd, sm); if (r < 0) { streaming_message_t *e = streaming_msg_create_code(SMT_STOP, SM_CODE_UNDEFINED_ERROR); streaming_target_deliver2(ts->output, e); tvhlog(LOG_ERR, "timeshift", "ts %d could not read buffer", ts->id); return -1; } tvhtrace("timeshift", "ts %d read msg %p (%"PRIssize_t")", ts->id, *sm, r); /* Incomplete */ if (r == 0) { lseek(*fd, *cur_off, SEEK_SET); return 0; } /* Update */ *cur_off += r; /* Special case - EOF */ if (r == sizeof(size_t) || *cur_off > (*cur_file)->size) { close(*fd); *fd = -1; pthread_mutex_lock(&ts->rdwr_mutex); *cur_file = timeshift_filemgr_next(*cur_file, NULL, 0); pthread_mutex_unlock(&ts->rdwr_mutex); *cur_off = 0; // reset *wait = 0; /* Check SMT_START index */ } else { streaming_message_t *ssm = _timeshift_find_sstart(*cur_file, (*sm)->sm_time); if (ssm && ssm->sm_data != ts->smt_start) { streaming_target_deliver2(ts->output, streaming_msg_clone(ssm)); if (ts->smt_start) streaming_start_unref(ts->smt_start); ts->smt_start = ssm->sm_data; atomic_add(&ts->smt_start->ss_refcount, 1); } } } return 0; }
static void* timeshift_reaper_callback ( void *p ) { char *dpath; timeshift_file_t *tsf; timeshift_index_iframe_t *ti; timeshift_index_data_t *tid; streaming_message_t *sm; pthread_mutex_lock(×hift_reaper_lock); while (timeshift_reaper_run) { /* Get next */ tsf = TAILQ_FIRST(×hift_reaper_list); if (!tsf) { pthread_cond_wait(×hift_reaper_cond, ×hift_reaper_lock); continue; } TAILQ_REMOVE(×hift_reaper_list, tsf, link); pthread_mutex_unlock(×hift_reaper_lock); if (tsf->path) { tvhtrace("timeshift", "remove file %s", tsf->path); /* Remove */ unlink(tsf->path); dpath = dirname(tsf->path); if (rmdir(dpath) == -1) if (errno != ENOTEMPTY) tvhlog(LOG_ERR, "timeshift", "failed to remove %s [e=%s]", dpath, strerror(errno)); } else { tvhtrace("timeshift", "remove RAM segment (time %li)", (long)tsf->time); } /* Free memory */ while ((ti = TAILQ_FIRST(&tsf->iframes))) { TAILQ_REMOVE(&tsf->iframes, ti, link); free(ti); } while ((tid = TAILQ_FIRST(&tsf->sstart))) { TAILQ_REMOVE(&tsf->sstart, tid, link); sm = tid->data; streaming_msg_free(sm); free(tid); } free(tsf->path); free(tsf->ram); free(tsf); pthread_mutex_lock(×hift_reaper_lock); } pthread_mutex_unlock(×hift_reaper_lock); tvhtrace("timeshift", "reaper thread exit"); return NULL; }
static void timeshift_reaper_remove ( timeshift_file_t *tsf ) { if (tvhtrace_enabled()) { if (tsf->path) tvhtrace("timeshift", "queue file for removal %s", tsf->path); else tvhtrace("timeshift", "queue file for removal - RAM segment time %li", (long)tsf->time); } pthread_mutex_lock(×hift_reaper_lock); TAILQ_INSERT_TAIL(×hift_reaper_list, tsf, link); pthread_cond_signal(×hift_reaper_cond); pthread_mutex_unlock(×hift_reaper_lock); }
/* * Output packet */ static int _timeshift_read ( timeshift_t *ts, timeshift_seek_t *seek, streaming_message_t **sm, int *wait ) { timeshift_file_t *tsf = seek->file; ssize_t r; off_t off = 0; *sm = NULL; if (tsf) { /* Open file */ if (tsf->rfd < 0 && !tsf->ram) { tsf->rfd = tvh_open(tsf->path, O_RDONLY, 0); tvhtrace(LS_TIMESHIFT, "ts %d open file %s (fd %i)", ts->id, tsf->path, tsf->rfd); if (tsf->rfd < 0) return -1; } if (tsf->rfd >= 0) if ((off = lseek(tsf->rfd, tsf->roff, SEEK_SET)) != tsf->roff) tvherror(LS_TIMESHIFT, "ts %d seek to %s failed (off %"PRId64" != %"PRId64"): %s", ts->id, tsf->path, (int64_t)tsf->roff, (int64_t)off, strerror(errno)); /* Read msg */ r = _read_msg(tsf, -1, sm); if (r < 0) { streaming_message_t *e = streaming_msg_create_code(SMT_STOP, SM_CODE_UNDEFINED_ERROR); streaming_target_deliver2(ts->output, e); tvhtrace(LS_TIMESHIFT, "ts %d seek to %jd (woff %jd) (fd %i)", ts->id, (intmax_t)off, (intmax_t)tsf->woff, tsf->rfd); tvherror(LS_TIMESHIFT, "ts %d could not read buffer", ts->id); return -1; } tvhtrace(LS_TIMESHIFT, "ts %d seek to %jd (fd %i) read msg %p/%"PRId64" (%"PRId64")", ts->id, (intmax_t)off, tsf->rfd, *sm, *sm ? (*sm)->sm_time : -1, (int64_t)r); /* Special case - EOF */ if (r <= sizeof(size_t) || tsf->roff > tsf->size || *sm == NULL) { timeshift_file_get(seek->file); /* _read_close decreases file reference */ _read_close(seek); _seek_set_file(seek, timeshift_filemgr_next(tsf, NULL, 0), 0); *wait = 0; tvhtrace(LS_TIMESHIFT, "ts %d eof, seek->file %p (prev %p)", ts->id, seek->file, tsf); timeshift_filemgr_dump(ts); } } return 0; }
void linuxdvb_ca_enqueue_capmt(linuxdvb_ca_t *lca, uint8_t slot, const uint8_t *ptr, int len, uint8_t list_mgmt, uint8_t cmd_id) { linuxdvb_ca_capmt_t *lcc; int c = 1; if (!lca) return; if (lca->lca_capmt_query && cmd_id == CA_PMT_CMD_ID_OK_DESCRAMBLING) c = 2; while (c--) { lcc = calloc(1, sizeof(*lcc)); if (!lcc) return; lcc->data = malloc(len); lcc->len = len; lcc->slot = slot; lcc->list_mgmt = list_mgmt; lcc->cmd_id = (c ? CA_PMT_CMD_ID_QUERY : cmd_id); memcpy(lcc->data, ptr, len); TAILQ_INSERT_TAIL(&lca->lca_capmt_queue, lcc, lcc_link); tvhtrace("en50221", "%s CAPMT enqueued (%s)", ca_pmt_cmd_id2str(lcc->cmd_id), ca_pmt_list_mgmt2str(lcc->list_mgmt)); } gtimer_arm_ms(&lca->lca_capmt_queue_timer, linuxdvb_ca_process_capmt_queue, lca, 50); }
/* * Send the status message */ static void timeshift_fill_status ( timeshift_t *ts, timeshift_status_t *status, int64_t current_time ) { int active = 0; int64_t start, end; start = _timeshift_first_time(ts, &active); end = ts->buf_time; if (ts->state <= TS_LIVE) { current_time = end; } else { if (current_time < 0) current_time = 0; if (current_time > end) current_time = end; } status->full = ts->full; tvhtrace(LS_TIMESHIFT, "ts %d status start %"PRId64" end %"PRId64 " current %"PRId64" state %d", ts->id, start, end, current_time, ts->state); status->shift = ts_rescale_inv(end - current_time, 1000000); if (active) { status->pts_start = ts_rescale_inv(start, 1000000); status->pts_end = ts_rescale_inv(end, 1000000); } else { status->pts_start = PTS_UNSET; status->pts_end = PTS_UNSET; } }
static void * thread_wrapper ( void *p ) { struct thread_state *ts = p; sigset_t set; #if defined(PLATFORM_LINUX) /* Set name */ prctl(PR_SET_NAME, ts->name); #elif defined(PLATFORM_FREEBSD) /* Set name of thread */ pthread_set_name_np(pthread_self(), ts->name); #elif defined(PLATFORM_DARWIN) pthread_setname_np(ts->name); #endif sigemptyset(&set); sigaddset(&set, SIGTERM); pthread_sigmask(SIG_UNBLOCK, &set, NULL); signal(SIGTERM, doexit); /* Run */ tvhtrace("thread", "created thread %ld [%s / %p(%p)]", (long)pthread_self(), ts->name, ts->run, ts->arg); void *r = ts->run(ts->arg); free(ts); return r; }
/* * Process directory * * Note: should we follow symlinks? */ static void scanfile_load_dir ( const char *path, const char *type, int lvl ) { char p[256]; fb_dir *dir; fb_dirent *de; tvhtrace("scanfile", "load dir %s", path); if (lvl >= 3) return; if (!(dir = fb_opendir(path))) return; lvl++; while ((de = fb_readdir(dir))) { if (*de->name == '.') continue; if (de->type == FB_DIR) { snprintf(p, sizeof(p), "%s/%s", path, de->name); scanfile_load_dir(p, de->name, lvl+1); } else if (type) { scanfile_load_file(type, dir, de->name); } } fb_closedir(dir); }
/* * Process mux entry */ static void scanfile_load_one ( scanfile_network_t *net, const char *line ) { int r = 1; dvb_mux_conf_t *mux = calloc(1, sizeof(dvb_mux_conf_t)); switch (line[0]) { case 'A': r = scanfile_load_atsc(mux, line+1); break; case 'T': r = scanfile_load_dvbt(mux, line+1); break; case 'S': r = scanfile_load_dvbs(mux, line+1); break; case 'C': r = scanfile_load_dvbc(mux, line+1); break; } tvhtrace("scanfile", "[%s] %s", line, r ? "FAIL" : "OK"); if (r) { free(mux); } else { LIST_INSERT_HEAD(&net->sfn_muxes, mux, dmc_link); } }
/* * Create/Find region entry * * TODO: not sure why I didn't use RB here! */ static scanfile_region_t * scanfile_region_create ( const char *type, const char *id, const char *desc ) { scanfile_region_t *reg; scanfile_region_list_t *list = NULL; if (!strcmp(type, "dvb-s")) list = &scanfile_regions_DVBS; else if (!strcmp(type, "dvb-t")) list = &scanfile_regions_DVBT; else if (!strcmp(type, "dvb-c")) list = &scanfile_regions_DVBC; else if (!strcmp(type, "atsc")) list = &scanfile_regions_ATSC; if (!list) return NULL; LIST_FOREACH(reg, list, sfr_link) { if (!strcmp(reg->sfr_id, id)) break; } if (!reg) { tvhtrace("scanfile", "%s region %s created", type, id); reg = calloc(1, sizeof(scanfile_region_t)); reg->sfr_id = strdup(id); reg->sfr_name = strdup(desc); LIST_INSERT_SORTED(list, reg, sfr_link, scanfile_region_cmp); } return reg; }
static void tvhcsa_csa_cbc_flush ( tvhcsa_t *csa, struct mpegts_service *s ) { #if ENABLE_DVBCSA tvhtrace(LS_CSA, "%p: CSA flush - descramble packets for service \"%s\" MAX=%d even=%d odd=%d fill=%d", csa,((mpegts_service_t *)s)->s_dvb_svcname, csa->csa_cluster_size,csa->csa_fill_even,csa->csa_fill_odd,csa->csa_fill); if(csa->csa_fill_even) { csa->csa_tsbbatch_even[csa->csa_fill_even].data = NULL; dvbcsa_bs_decrypt(csa->csa_key_even, csa->csa_tsbbatch_even, 184); csa->csa_fill_even = 0; } if(csa->csa_fill_odd) { csa->csa_tsbbatch_odd[csa->csa_fill_odd].data = NULL; dvbcsa_bs_decrypt(csa->csa_key_odd, csa->csa_tsbbatch_odd, 184); csa->csa_fill_odd = 0; } ts_recv_packet2(s, csa->csa_tsbcluster, csa->csa_fill * 188); csa->csa_fill = 0; #else #error "Unknown CSA descrambler" #endif }
/* * Process mux entry */ static int scanfile_load_one ( scanfile_network_t **net, const char *type, const char *name, const char *line ) { int r = 1; dvb_mux_conf_t *mux = malloc(sizeof(dvb_mux_conf_t)); switch (line[0]) { case 'A': r = scanfile_load_atsc(mux, line+1); break; case 'T': r = scanfile_load_dvbt(mux, line+1); break; case 'S': r = scanfile_load_dvbs(mux, line+1); break; case 'C': r = scanfile_load_dvbc(mux, line+1); break; } tvhtrace("scanfile", "[%s] %s", line, r ? "FAIL" : "OK"); if (r) { free(mux); } else { if (*net == NULL && scanfile_create_network(net, type, name, mux->dmc_fe_delsys)) { free(mux); return -1; } LIST_INSERT_HEAD(&(*net)->sfn_muxes, mux, dmc_link); } return 1; }
static int linuxdvb_ca_mmi_enq_cb(void *arg, uint8_t slot_id, uint16_t session_num, uint8_t blind_answ, uint8_t exp_answ_len, uint8_t *text, uint32_t text_size) { linuxdvb_ca_t * lca = arg; char buffer[256]; snprintf(buffer, sizeof(buffer), "%.*s", text_size, text); tvhlog(LOG_NOTICE, "en50221", "MMI enquiry from CAM in slot %u: %s (%s%u digits)", slot_id, buffer, blind_answ ? "blind " : "" , exp_answ_len); if (lca->lca_pin_reply && (strlen((char *) lca->lca_pin_str) == exp_answ_len) && strstr((char *) buffer, lca->lca_pin_match_str)) { tvhtrace("en50221", "answering to PIN enquiry"); en50221_app_mmi_answ(lca->lca_mmi_resource, session_num, MMI_ANSW_ID_ANSWER, (uint8_t *) lca->lca_pin_str, exp_answ_len); } en50221_app_mmi_close(lca->lca_mmi_resource, session_num, MMI_CLOSE_MMI_CMD_ID_IMMEDIATE, 0); return 0; }
static void timeshift_reaper_remove ( timeshift_file_t *tsf ) { tvhtrace("timeshift", "queue file for removal %s", tsf->path); pthread_mutex_lock(×hift_reaper_lock); TAILQ_INSERT_TAIL(×hift_reaper_list, tsf, link); pthread_cond_signal(×hift_reaper_cond); pthread_mutex_unlock(×hift_reaper_lock); }
/* * Connected */ static int iptv_rtsp_header ( http_client_t *hc ) { iptv_mux_t *im = hc->hc_aux; rtsp_priv_t *rp; int r; if (im == NULL) { /* teardown (or teardown timeout) */ if (hc->hc_cmd == RTSP_CMD_TEARDOWN) { pthread_mutex_lock(&global_lock); mtimer_arm_rel(&hc->hc_close_timer, iptv_rtsp_close_cb, hc, 0); pthread_mutex_unlock(&global_lock); } return 0; } if (hc->hc_cmd == RTSP_CMD_GET_PARAMETER && hc->hc_code != HTTP_STATUS_OK) { tvhtrace("iptv", "GET_PARAMETER command returned invalid error code %d for '%s', " "fall back to OPTIONS in keep alive loop.", hc->hc_code, im->mm_iptv_url_raw); hc->hc_rtsp_keep_alive_cmd = RTSP_CMD_OPTIONS; return 0; } if (hc->hc_code != HTTP_STATUS_OK) { tvherror("iptv", "invalid error code %d for '%s'", hc->hc_code, im->mm_iptv_url_raw); return 0; } rp = im->im_data; switch (hc->hc_cmd) { case RTSP_CMD_SETUP: r = rtsp_setup_decode(hc, 0); if (r >= 0) { rtsp_play(hc, rp->path, rp->query); rp->play = 1; } break; case RTSP_CMD_PLAY: // Now let's set peer port for RTCP // Use the HTTP host for sending RTCP reports, NOT the hc_rtp_dest (which is where the stream is sent) if (udp_connect(rp->rtcp_info->connection, "rtcp", hc->hc_host, hc->hc_rtcp_server_port)) { tvhlog(LOG_WARNING, "rtsp", "Can't connect to remote, RTCP receiver reports won't be sent"); } hc->hc_cmd = HTTP_CMD_NONE; pthread_mutex_lock(&global_lock); iptv_input_mux_started(hc->hc_aux); mtimer_arm_rel(&rp->alive_timer, iptv_rtsp_alive_cb, im, sec2mono(MAX(1, (hc->hc_rtp_timeout / 2) - 1))); pthread_mutex_unlock(&global_lock); break; default: break; } return 0; }
static void * mtimer_thread(void *aux) { mtimer_t *mti; mti_callback_t *cb; int64_t now, next; #if ENABLE_GTIMER_CHECK int64_t mtm; const char *id; const char *fcn; #endif while (tvheadend_is_running()) { now = mdispatch_clock_update(); /* Global monoclock timers */ pthread_mutex_lock(&global_lock); next = now + sec2mono(3600); while((mti = LIST_FIRST(&mtimers)) != NULL) { if (mti->mti_expire > now) { next = mti->mti_expire; break; } #if ENABLE_GTIMER_CHECK mtm = getmonoclock(); id = mti->mti_id; fcn = mti->mti_fcn; #endif cb = mti->mti_callback; LIST_REMOVE(mti, mti_link); mti->mti_callback = NULL; cb(mti->mti_opaque); #if ENABLE_GTIMER_CHECK mtm = getmonoclock() - mtm; if (mtm > 10000) tvhtrace("mtimer", "%s:%s duration %"PRId64"us", id, fcn, mtm); #endif } /* Periodic updates */ if (next > mtimer_periodic) next = mtimer_periodic; /* Wait */ tvh_cond_timedwait(&mtimer_cond, &global_lock, next); pthread_mutex_unlock(&global_lock); } return NULL; }
mpegts_mux_t * tsfile_mux_create ( mpegts_network_t *mn ) { mpegts_mux_t *mm = mpegts_mux_create1(NULL, mn, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, NULL); mm->mm_config_save = iptv_mux_config_save; tvhtrace("tsfile", "mm created %p", mm); return mm; }
static int linuxdvb_ca_mmi_close_cb(void *arg, uint8_t slot_id, uint16_t session_num, uint8_t cmd_id, uint8_t delay) { tvhtrace("en50221", "mmi close cb received for slot %u session_num %u " "cmd_id 0x%02x delay %u" , slot_id, session_num, cmd_id, delay); return 0; }
static int en50221_app_unknown_message(void *arg, uint8_t slot_id, uint16_t session_num, uint32_t resource_id, uint8_t *data, uint32_t data_length) { tvhtrace("en50221", "unknown message slot_id %u, session_num %u, resource_id %x", slot_id, session_num, resource_id); tvhlog_hexdump("en50221", data, data_length); return 0; }
mpegts_mux_t * tsfile_mux_create ( const char *uuid, mpegts_network_t *mn ) { mpegts_mux_t *mm = mpegts_mux_create1(uuid, mn, MPEGTS_ONID_NONE, MPEGTS_TSID_NONE, NULL); mm->mm_config_save = iptv_mux_config_save; mm->mm_epg = MM_EPG_DISABLE; tvhtrace("tsfile", "mm created %p", mm); return mm; }
int tvhcsa_set_type( tvhcsa_t *csa, struct mpegts_service *s, int type ) { if (csa->csa_type == type) return 0; if (csa->csa_descramble) return -1; switch (type) { case DESCRAMBLER_CSA_CBC: csa->csa_descramble = tvhcsa_csa_cbc_descramble; csa->csa_flush = tvhcsa_csa_cbc_flush; csa->csa_keylen = 8; #if ENABLE_DVBCSA csa->csa_cluster_size = dvbcsa_bs_batch_size(); #else csa->csa_cluster_size = 0; #endif csa->csa_fill_size = 3 * csa->csa_cluster_size; tvhtrace(LS_CSA, "%p: service \"%s\" using CSA batch size = %d for decryption", csa, ((mpegts_service_t *)s)->s_dvb_svcname, csa->csa_cluster_size ); csa->csa_tsbcluster = malloc(csa->csa_fill_size * 188); #if ENABLE_DVBCSA csa->csa_tsbbatch_even = malloc((csa->csa_cluster_size + 1) * sizeof(struct dvbcsa_bs_batch_s)); csa->csa_tsbbatch_odd = malloc((csa->csa_cluster_size + 1) * sizeof(struct dvbcsa_bs_batch_s)); csa->csa_key_even = dvbcsa_bs_key_alloc(); csa->csa_key_odd = dvbcsa_bs_key_alloc(); #endif break; case DESCRAMBLER_DES_NCB: csa->csa_priv = des_get_priv_struct(); csa->csa_descramble = tvhcsa_des_ncb_descramble; csa->csa_flush = tvhcsa_empty_flush; csa->csa_keylen = 8; break; case DESCRAMBLER_AES_ECB: csa->csa_priv = aes_get_priv_struct(); csa->csa_descramble = tvhcsa_aes_ecb_descramble; csa->csa_flush = tvhcsa_empty_flush; csa->csa_keylen = 8; break; case DESCRAMBLER_AES128_ECB: csa->csa_priv = aes128_get_priv_struct(); csa->csa_descramble = tvhcsa_aes128_ecb_descramble; csa->csa_flush = tvhcsa_empty_flush; csa->csa_keylen = 16; break; default: assert(0); } csa->csa_type = type; return 0; }
static int linuxdvb_ca_rm_reply_cb(void *arg, uint8_t slot_id, uint16_t session_num, uint32_t resource_id_count, uint32_t *_resource_ids) { linuxdvb_ca_t * lca = arg; tvhtrace("en50221", "rm reply cb received for slot %d, count %u", slot_id, resource_id_count); uint32_t i; for(i=0; i< resource_id_count; i++) { tvhtrace("en50221", "CAM provided resource id: %08x", _resource_ids[i]); } if (en50221_app_rm_changed(lca->lca_rm_resource, session_num)) { tvherror("en50221", "failed to send RM reply on slot %u", slot_id); } return 0; }
int diseqc_voltage_off(int fe_fd) { int err; tvhtrace("diseqc", "sending diseqc voltage off command"); if ((err = ioctl(fe_fd, FE_SET_VOLTAGE, SEC_VOLTAGE_OFF))) { tvhlog(LOG_ERR, "diseqc", "error sending diseqc voltage off command"); return err; } return 0; }
static const char * satip_rtsp_setup_find(const char *prefix, tvh2satip_t *tbl, int src, const char *defval) { while (tbl->t >= 0) { if (tbl->t == src) return tbl->s; tbl++; } tvhtrace("satip", "%s - cannot translate %d", prefix, src); return defval; }
static int linuxdvb_ca_session_cb (void *arg, int reason, uint8_t slot_id, uint16_t session_num, uint32_t rid) { linuxdvb_ca_t * lca = arg; if (reason == S_SCALLBACK_REASON_CAMCONNECTING) { tvhtrace("en50221", "0x%08x session %u connecting", rid, session_num); return 0; } if (reason == S_SCALLBACK_REASON_CAMCONNECTED) { tvhtrace("en50221", "0x%08x session %u connected", rid, session_num); switch(rid) { case EN50221_APP_RM_RESOURCEID: en50221_app_rm_enq(lca->lca_rm_resource, session_num); break; case EN50221_APP_AI_RESOURCEID: case TS101699_APP_AI_RESOURCEID: case CIPLUS13_APP_AI_RESOURCEID: lca->lca_ai_version = rid & 0x3f; lca->lca_ai_session_number = session_num; en50221_app_ai_enquiry(lca->lca_ai_resource, session_num); ciplus13_app_ai_data_rate_info(lca, lca->lca_high_bitrate_mode ? CIPLUS13_DATA_RATE_96_MBPS : CIPLUS13_DATA_RATE_72_MBPS ); break; case EN50221_APP_CA_RESOURCEID: en50221_app_ca_info_enq(lca->lca_ca_resource, session_num); lca->lca_ca_session_number = session_num; break; case EN50221_APP_MMI_RESOURCEID: case EN50221_APP_DATETIME_RESOURCEID: break; default: tvhtrace("en50221", "session %u with unknown rid 0x%08x is connected", session_num, rid); } return 0; } if (reason == S_SCALLBACK_REASON_CLOSE) { tvhtrace("en50221", "0x%08x session %u close", rid, session_num); switch(rid) { case EN50221_APP_CA_RESOURCEID: dvbcam_unregister_cam(lca, 0); lca->lca_cam_menu_string[0] = 0; } return 0; } if (reason == S_SCALLBACK_REASON_TC_CONNECT) { tvhtrace("en50221", "0x%08x session %u tc connect", rid, session_num); return 0; } tvhtrace("en50221", "unhandled session callback - reason %d slot_id %u " "session_num %u resource_id %x", reason, slot_id, session_num, rid); return 0; }
static int linuxdvb_ca_rm_changed_cb(void *arg, uint8_t slot_id, uint16_t session_num) { linuxdvb_ca_t * lca = arg; tvhtrace("en50221", "rm changed cb received for slot %d", slot_id); if (en50221_app_rm_enq(lca->lca_rm_resource, session_num)) { tvherror("en50221", "failed to send ENQ to slot %d", slot_id); } return 0; }
/* * Add multiplex */ void tsfile_add_file ( const char *path ) { mpegts_input_t *mi; mpegts_mux_t *mm; tvhtrace("tsfile", "add file %s", path); /* Create logical instance */ mm = tsfile_mux_create(&tsfile_network); /* Create physical instance (for each tuner) */ LIST_FOREACH(mi, &tsfile_inputs, mi_global_link) tsfile_mux_instance_create(path, mi, mm); }
static int linuxdvb_ca_dt_enquiry_cb(void *arg, uint8_t slot_id, uint16_t session_num, uint8_t response_int) { linuxdvb_ca_t * lca = arg; tvhtrace("en50221", "datetime enquiry cb received for slot %d", slot_id); if (en50221_app_datetime_send(lca->lca_dt_resource, session_num, time(NULL), -1)) { tvherror("en50221", "Failed to send datetime to slot %d", slot_id); } return 0; }
tsfile_mux_instance_t * tsfile_mux_instance_create ( const char *path, mpegts_input_t *mi, mpegts_mux_t *mm ) { #define tsfile_mux_instance_class mpegts_mux_instance_class tsfile_mux_instance_t *mmi = mpegts_mux_instance_create(tsfile_mux_instance, NULL, mi, mm); #undef tsfile_mux_instance_class mmi->mmi_tsfile_path = strdup(path); mmi->mmi_tsfile_pcr_pid = MPEGTS_PID_NONE; tvhtrace("tsfile", "mmi created %p path %s", mmi, mmi->mmi_tsfile_path); return mmi; }