static enum cmd_error_code track_untrack_pid(enum cmd_type cmd_type, const char *cmd_str, const char *session_name, const char *pid_string, int all, struct mi_writer *writer) { int ret, success = 1 , i; enum cmd_error_code retval = CMD_SUCCESS; int *pid_list = NULL; int nr_pids; struct lttng_domain dom; struct lttng_handle *handle = NULL; int (*cmd_func)(struct lttng_handle *handle, int pid); switch (cmd_type) { case CMD_TRACK: cmd_func = lttng_track_pid; break; case CMD_UNTRACK: cmd_func = lttng_untrack_pid; break; default: ERR("Unknown command"); retval = CMD_ERROR; goto end; } memset(&dom, 0, sizeof(dom)); if (opt_kernel) { dom.type = LTTNG_DOMAIN_KERNEL; } else if (opt_userspace) { dom.type = LTTNG_DOMAIN_UST; } else { /* Checked by the caller. */ assert(0); } ret = parse_pid_string(pid_string, all, &pid_list, &nr_pids); if (ret != CMD_SUCCESS) { ERR("Error parsing PID string"); retval = CMD_ERROR; goto end; } handle = lttng_create_handle(session_name, &dom); if (handle == NULL) { retval = CMD_ERROR; goto end; } if (writer) { /* Open process element */ ret = mi_lttng_targets_open(writer); if (ret) { retval = CMD_ERROR; goto end; } } for (i = 0; i < nr_pids; i++) { DBG("%s PID %d", cmd_str, pid_list[i]); ret = cmd_func(handle, pid_list[i]); if (ret) { switch (-ret) { case LTTNG_ERR_PID_TRACKED: WARN("PID %i already tracked in session %s", pid_list[i], session_name); success = 1; retval = CMD_SUCCESS; break; case LTTNG_ERR_PID_NOT_TRACKED: WARN("PID %i not tracked in session %s", pid_list[i], session_name); success = 1; retval = CMD_SUCCESS; break; default: ERR("%s", lttng_strerror(ret)); success = 0; retval = CMD_ERROR; break; } } else { MSG("PID %i %sed in session %s", pid_list[i], cmd_str, session_name); success = 1; } /* Mi */ if (writer) { ret = mi_lttng_pid_target(writer, pid_list[i], 1); if (ret) { retval = CMD_ERROR; goto end; } ret = mi_lttng_writer_write_element_bool(writer, mi_lttng_element_success, success); if (ret) { retval = CMD_ERROR; goto end; } ret = mi_lttng_writer_close_element(writer); if (ret) { retval = CMD_ERROR; goto end; } } } if (writer) { /* Close targets element */ ret = mi_lttng_writer_close_element(writer); if (ret) { retval = CMD_ERROR; goto end; } } end: if (handle) { lttng_destroy_handle(handle); } free(pid_list); return retval; }
static dvb_channels_list *dvb_get_channels(struct mp_log *log, int cfg_full_transponder, char *filename, int type) { dvb_channels_list *list; FILE *f; char line[CHANNEL_LINE_LEN], *colon; if (!filename) return NULL; int fields, cnt, k; int has8192, has0; dvb_channel_t *ptr, *tmp, chn; char tmp_lcr[256], tmp_hier[256], inv[256], bw[256], cr[256], mod[256], transm[256], gi[256], vpid_str[256], apid_str[256], tpid_str[256], vdr_par_str[256], vdr_loc_str[256]; const char *cbl_conf = "%d:%255[^:]:%d:%255[^:]:%255[^:]:%255[^:]:%255[^:]\n"; const char *sat_conf = "%d:%c:%d:%d:%255[^:]:%255[^:]\n"; const char *ter_conf = "%d:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]:%255[^:]\n"; const char *atsc_conf = "%d:%255[^:]:%255[^:]:%255[^:]\n"; const char *vdr_conf = "%d:%255[^:]:%255[^:]:%d:%255[^:]:%255[^:]:%255[^:]:%*255[^:]:%d:%*d:%*d:%*d\n%n"; mp_verbose(log, "CONFIG_READ FILE: %s, type: %d\n", filename, type); if ((f = fopen(filename, "r")) == NULL) { mp_fatal(log, "CAN'T READ CONFIG FILE %s\n", filename); return NULL; } list = malloc(sizeof(dvb_channels_list)); if (list == NULL) { fclose(f); mp_verbose(log, "DVB_GET_CHANNELS: couldn't malloc enough memory\n"); return NULL; } ptr = &chn; list->NUM_CHANNELS = 0; list->channels = NULL; while (!feof(f)) { if (fgets(line, CHANNEL_LINE_LEN, f) == NULL) continue; if ((line[0] == '#') || (strlen(line) == 0)) continue; colon = strchr(line, ':'); if (colon) { k = colon - line; if (!k) continue; // In some modern VDR-style configs, channel name also has bouquet after ;. // Parse that off, we ignore it. char *bouquet_sep = strchr(line, ';'); int channel_name_length = k; if (bouquet_sep && bouquet_sep < colon) channel_name_length = bouquet_sep - line; ptr->name = malloc(channel_name_length + 1); if (!ptr->name) continue; av_strlcpy(ptr->name, line, channel_name_length + 1); } else { continue; } k++; vpid_str[0] = apid_str[0] = tpid_str[0] = 0; vdr_loc_str[0] = vdr_par_str[0] = 0; ptr->pids_cnt = 0; ptr->freq = 0; ptr->is_dvb_s2 = false; ptr->service_id = -1; ptr->stream_id = NO_STREAM_ID_FILTER; ptr->inv = INVERSION_AUTO; // Check if VDR-type channels.conf-line - then full line is consumed by the scan. int num_chars = 0; fields = sscanf(&line[k], vdr_conf, &ptr->freq, vdr_par_str, vdr_loc_str, &ptr->srate, vpid_str, apid_str, tpid_str, &ptr->service_id, &num_chars); if (num_chars == strlen(&line[k])) { // It's a VDR-style config line. parse_vdr_par_string(vdr_par_str, ptr); // We still need the special SAT-handling here. if (type != TUNER_TER && type != TUNER_CBL && type != TUNER_ATSC) { ptr->freq *= 1000UL; ptr->srate *= 1000UL; ptr->tone = -1; ptr->inv = INVERSION_AUTO; ptr->cr = FEC_AUTO; if (vdr_loc_str[0]) { // In older vdr config format, this field contained the DISEQc information. // If it is numeric, assume that's it. int diseqc_info = 0; int valid_digits = 0; if (sscanf(vdr_loc_str, "%d%n", &diseqc_info, &valid_digits) == 1) { if (valid_digits == strlen(vdr_loc_str)) { ptr->diseqc = diseqc_info; if ((ptr->diseqc > 4) || (ptr->diseqc < 0)) continue; if (ptr->diseqc > 0) ptr->diseqc--; } } } mp_verbose(log, "SAT, NUM: %d, NUM_FIELDS: %d, NAME: %s, " "FREQ: %d, SRATE: %d, POL: %c, DISEQC: %d, S2: %s, " "StreamID: %d, SID: %d", list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate, ptr->pol, ptr->diseqc, ptr->is_dvb_s2 ? "yes" : "no", ptr->stream_id, ptr->service_id); } else { mp_verbose(log, "VDR, NUM: %d, NUM_FIELDS: %d, NAME: %s, " "FREQ: %d, SRATE: %d", list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate); } } else if (type == TUNER_TER) { fields = sscanf(&line[k], ter_conf, &ptr->freq, inv, bw, cr, tmp_lcr, mod, transm, gi, tmp_hier, vpid_str, apid_str); mp_verbose(log, "TER, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d", list->NUM_CHANNELS, fields, ptr->name, ptr->freq); } else if (type == TUNER_CBL) { fields = sscanf(&line[k], cbl_conf, &ptr->freq, inv, &ptr->srate, cr, mod, vpid_str, apid_str); mp_verbose(log, "CBL, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, " "SRATE: %d", list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate); } #ifdef DVB_ATSC else if (type == TUNER_ATSC) { fields = sscanf(&line[k], atsc_conf, &ptr->freq, mod, vpid_str, apid_str); mp_verbose(log, "ATSC, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d\n", list->NUM_CHANNELS, fields, ptr->name, ptr->freq); } #endif else { //SATELLITE fields = sscanf(&line[k], sat_conf, &ptr->freq, &ptr->pol, &ptr->diseqc, &ptr->srate, vpid_str, apid_str); ptr->pol = mp_toupper(ptr->pol); ptr->freq *= 1000UL; ptr->srate *= 1000UL; ptr->tone = -1; ptr->inv = INVERSION_AUTO; ptr->cr = FEC_AUTO; if ((ptr->diseqc > 4) || (ptr->diseqc < 0)) continue; if (ptr->diseqc > 0) ptr->diseqc--; mp_verbose(log, "SAT, NUM: %d, NUM_FIELDS: %d, NAME: %s, FREQ: %d, " "SRATE: %d, POL: %c, DISEQC: %d", list->NUM_CHANNELS, fields, ptr->name, ptr->freq, ptr->srate, ptr->pol, ptr->diseqc); } if (parse_pid_string(log, vpid_str, ptr)) fields++; if (parse_pid_string(log, apid_str, ptr)) fields++; /* If we do not know the service_id, PMT can not be extracted. Teletext decoding will fail without PMT. */ if (ptr->service_id != -1) { if (parse_pid_string(log, tpid_str, ptr)) fields++; } if ((fields < 2) || (ptr->pids_cnt <= 0) || (ptr->freq == 0) || (strlen(ptr->name) == 0)) continue; /* Add some PIDs which are mandatory in DVB, * and contain human-readable helpful data. */ /* This is the STD, the service description table. * It contains service names and such, ffmpeg decodes it. */ ptr->pids[ptr->pids_cnt] = 0x0011; ptr->pids_cnt++; /* This is the EIT, which contains EPG data. * ffmpeg can not decode it (yet), but e.g. VLC * shows what was recorded. */ ptr->pids[ptr->pids_cnt] = 0x0012; ptr->pids_cnt++; if (ptr->service_id != -1) { /* We have the PMT-PID in addition. This will be found later, when we tune to the channel. Push back here to create the additional demux. */ ptr->pids[ptr->pids_cnt] = -1; // Placeholder. ptr->pids_cnt++; } has8192 = has0 = 0; for (cnt = 0; cnt < ptr->pids_cnt; cnt++) { if (ptr->pids[cnt] == 8192) has8192 = 1; if (ptr->pids[cnt] == 0) has0 = 1; } /* 8192 is the pseudo-PID for full TP dump, enforce that if requested. */ if (!has8192 && cfg_full_transponder) has8192 = 1; if (has8192) { ptr->pids[0] = 8192; ptr->pids_cnt = 1; } else if (!has0) { ptr->pids[ptr->pids_cnt] = 0; //PID 0 is the PAT ptr->pids_cnt++; } mp_verbose(log, " PIDS: "); for (cnt = 0; cnt < ptr->pids_cnt; cnt++) mp_verbose(log, " %d ", ptr->pids[cnt]); mp_verbose(log, "\n"); if ((type == TUNER_TER) || (type == TUNER_CBL)) { if (!strcmp(inv, "INVERSION_ON")) { ptr->inv = INVERSION_ON; } else if (!strcmp(inv, "INVERSION_OFF")) { ptr->inv = INVERSION_OFF; } else { ptr->inv = INVERSION_AUTO; } if (!strcmp(cr, "FEC_1_2")) { ptr->cr = FEC_1_2; } else if (!strcmp(cr, "FEC_2_3")) { ptr->cr = FEC_2_3; } else if (!strcmp(cr, "FEC_3_4")) { ptr->cr = FEC_3_4; } else if (!strcmp(cr, "FEC_4_5")) { ptr->cr = FEC_4_5; } else if (!strcmp(cr, "FEC_6_7")) { ptr->cr = FEC_6_7; } else if (!strcmp(cr, "FEC_8_9")) { ptr->cr = FEC_8_9; } else if (!strcmp(cr, "FEC_5_6")) { ptr->cr = FEC_5_6; } else if (!strcmp(cr, "FEC_7_8")) { ptr->cr = FEC_7_8; } else if (!strcmp(cr, "FEC_NONE")) { ptr->cr = FEC_NONE; } else { ptr->cr = FEC_AUTO; } } if (type == TUNER_TER || type == TUNER_CBL || type == TUNER_ATSC) { if (!strcmp(mod, "QAM_128")) { ptr->mod = QAM_128; } else if (!strcmp(mod, "QAM_256")) { ptr->mod = QAM_256; } else if (!strcmp(mod, "QAM_64")) { ptr->mod = QAM_64; } else if (!strcmp(mod, "QAM_32")) { ptr->mod = QAM_32; } else if (!strcmp(mod, "QAM_16")) { ptr->mod = QAM_16; #ifdef DVB_ATSC } else if (!strcmp(mod, "VSB_8") || !strcmp(mod, "8VSB")) { ptr->mod = VSB_8; } else if (!strcmp(mod, "VSB_16") || !strcmp(mod, "16VSB")) { ptr->mod = VSB_16; } else if (!strcmp(mod, "QAM_AUTO")) { ptr->mod = QAM_AUTO; } #endif } if (type == TUNER_TER) { if (!strcmp(bw, "BANDWIDTH_6_MHZ")) { ptr->bw = BANDWIDTH_6_MHZ; } else if (!strcmp(bw, "BANDWIDTH_7_MHZ")) { ptr->bw = BANDWIDTH_7_MHZ; } else if (!strcmp(bw, "BANDWIDTH_8_MHZ")) { ptr->bw = BANDWIDTH_8_MHZ; } if (!strcmp(transm, "TRANSMISSION_MODE_2K")) { ptr->trans = TRANSMISSION_MODE_2K; } else if (!strcmp(transm, "TRANSMISSION_MODE_8K")) { ptr->trans = TRANSMISSION_MODE_8K; } else if (!strcmp(transm, "TRANSMISSION_MODE_AUTO")) { ptr->trans = TRANSMISSION_MODE_AUTO; } if (!strcmp(gi, "GUARD_INTERVAL_1_32")) { ptr->gi = GUARD_INTERVAL_1_32; } else if (!strcmp(gi, "GUARD_INTERVAL_1_16")) { ptr->gi = GUARD_INTERVAL_1_16; } else if (!strcmp(gi, "GUARD_INTERVAL_1_8")) { ptr->gi = GUARD_INTERVAL_1_8; } else if (!strcmp(gi, "GUARD_INTERVAL_1_4")) { ptr->gi = GUARD_INTERVAL_1_4; } else { ptr->gi = GUARD_INTERVAL_AUTO; } if (!strcmp(tmp_lcr, "FEC_1_2")) { ptr->cr_lp = FEC_1_2; } else if (!strcmp(tmp_lcr, "FEC_2_3")) { ptr->cr_lp = FEC_2_3; } else if (!strcmp(tmp_lcr, "FEC_3_4")) { ptr->cr_lp = FEC_3_4; } else if (!strcmp(tmp_lcr, "FEC_4_5")) { ptr->cr_lp = FEC_4_5; } else if (!strcmp(tmp_lcr, "FEC_6_7")) { ptr->cr_lp = FEC_6_7; } else if (!strcmp(tmp_lcr, "FEC_8_9")) { ptr->cr_lp = FEC_8_9; } else if (!strcmp(tmp_lcr, "FEC_5_6")) { ptr->cr_lp = FEC_5_6; } else if (!strcmp(tmp_lcr, "FEC_7_8")) { ptr->cr_lp = FEC_7_8; } else if (!strcmp(tmp_lcr, "FEC_NONE")) { ptr->cr_lp = FEC_NONE; } else { ptr->cr_lp = FEC_AUTO; } if (!strcmp(tmp_hier, "HIERARCHY_1")) { ptr->hier = HIERARCHY_1; } else if (!strcmp(tmp_hier, "HIERARCHY_2")) { ptr->hier = HIERARCHY_2; } else if (!strcmp(tmp_hier, "HIERARCHY_4")) { ptr->hier = HIERARCHY_4; } else if (!strcmp(tmp_hier, "HIERARCHY_AUTO")) { ptr->hier = HIERARCHY_AUTO; } else { ptr->hier = HIERARCHY_NONE; } } tmp = realloc(list->channels, sizeof(dvb_channel_t) * (list->NUM_CHANNELS + 1)); if (tmp == NULL) break; list->channels = tmp; memcpy(&(list->channels[list->NUM_CHANNELS]), ptr, sizeof(dvb_channel_t)); list->NUM_CHANNELS++; if (sizeof(dvb_channel_t) * list->NUM_CHANNELS >= 1024 * 1024) { mp_verbose(log, "dvbin.c, > 1MB allocated for channels struct, " "dropping the rest of the file\n"); break; } } fclose(f); if (list->NUM_CHANNELS == 0) { free(list->channels); free(list); return NULL; } list->current = 0; return list; }