|
SASC-NG
DVBSoftCAM
|
#include <stdlib.h>#include <stdio.h>#include <fcntl.h>#include <pthread.h>#include <sys/mman.h>#include <sys/poll.h>#include <sys/ioctl.h>#include <signal.h>#include <string.h>#include <getopt.h>#include <unistd.h>#include <errno.h>#include <assert.h>#include "list.h"#include <linux/dvb/dmx.h>#include <linux/dvb/frontend.h>#include <linux/dvb/version.h>#include "plugin_getsid.h"#include "msg_passing.h"#include "debug.h"Go to the source code of this file.
Classes | |
| struct | filter |
| struct | sidnum |
| struct | pat |
Defines | |
| #define | FE_SET_FRONTEND2 FE_SET_FRONTEND |
| #define | DBG_NAME "CHANNEL" |
| #define | PLUGIN_ID PLUGIN_GETSID |
| #define | MAX_PAT_SECTIONS 5 |
| #define | MAX_SIMULTANEOUS_PMT 32 |
Functions | |
| static | LIST_HEAD (getsidlist) |
| LIST_HEAD (sid_empty_queue) | |
| LIST_HEAD (sidnum_empty_queue) | |
| LIST_HEAD (epid_empty_queue) | |
| LIST_HEAD (dmxcmd_empty_queue) | |
| LIST_HEAD (sidmsg_empty_queue) | |
| LIST_HEAD (filt_empty_queue) | |
| void | free_sidmsg (struct sid_msg *sidmsg) |
| void | free_addsid_msg (void *msg) |
| static int | add_pid (int patfd, int pid) |
| static void | free_sid (struct sid *sid_ll) |
| static void | free_pat (struct pat *pat) |
| static int | read_pat (unsigned char *pes, struct pat *pat, unsigned int size) |
| unsigned char * | parse_ca (unsigned char *buf, unsigned char *ca, int len) |
| static int | read_nit (unsigned char *buf, struct nit_data *nit, unsigned int size) |
| static bool | cmp_wild (const char *pat, const char *s) |
| static bool | match_sid (int sid, const char *param) |
| static int | read_pmt (unsigned char *buf, struct filter *filt, struct sid_data *sid_data, unsigned int size) |
| static int | start (char *dmxdev, struct sid_data *sid_data, int timeout) |
| static int | check_av (unsigned char type) |
| struct sid * | find_pid (struct list_head *sidlist, unsigned int pid) |
| static void * | read_sid (void *arg) |
| static struct sid_data * | find_siddata_from_pc (struct parser_cmds *pc) |
| static void | clear_sid_data (struct sid_data *sid_data) |
| static void | fe_tune (struct parser_cmds *pc, struct poll_ll *fdptr, cmdret_t *result, int *ret, unsigned long int cmd, unsigned char *data) |
| static void | fe_close (struct parser_cmds *pc, struct poll_ll *fdptr, cmdret_t *result, int *ret, unsigned long int cmd, unsigned char *data) |
| static void | close_demux (struct parser_cmds *pc, struct poll_ll *fdptr, cmdret_t *result, int *ret, unsigned long int cmd, unsigned char *data) |
| static void | set_demux (struct parser_cmds *pc, struct poll_ll *fdptr, cmdret_t *result, int *ret, unsigned long int cmd, unsigned char *data) |
| static void | enable_msg (struct parser_cmds *pc, int enable) |
| static void | connect_sid (struct parser_adpt *pc_all) |
| static void | launch_sid () |
| static void | shutdown_sid () |
| static struct option * | parseopt_sid (arg_enum_t cmd) |
| int | __attribute__ ((constructor)) |
Variables | |
| static int | sid_opt = 0 |
| static int | opt_maxfilters = 2 |
| static int | opt_max_fail = 20 |
| static int | opt_allpids = 0 |
| static int | opt_resetpidmap = 0 |
| static int | opt_experimental = 0 |
| static int | opt_orbit = 0 |
| static char * | opt_ignore = 0 |
| static char * | opt_unseen = 0 |
| static int | opt_maxrestart = 0 |
| static struct option | Sid_Opts [] |
| static pthread_mutex_t | list_lock = PTHREAD_MUTEX_INITIALIZER |
| static struct plugin_cmd | plugin_cmds |
| #define DBG_NAME "CHANNEL" |
Definition at line 48 of file plugin_getsid.c.
| #define FE_SET_FRONTEND2 FE_SET_FRONTEND |
Definition at line 43 of file plugin_getsid.c.
Referenced by fe_ioctl(), and fe_tune().
| #define MAX_PAT_SECTIONS 5 |
Definition at line 69 of file plugin_getsid.c.
Referenced by read_pat(), and start().
| #define MAX_SIMULTANEOUS_PMT 32 |
Definition at line 79 of file plugin_getsid.c.
Referenced by parseopt_sid().
| #define PLUGIN_ID PLUGIN_GETSID |
Definition at line 49 of file plugin_getsid.c.
| int __attribute__ | ( | (constructor) | ) |
Definition at line 1092 of file plugin_getsid.c.
References plugin_cmd::list, list_add(), and plugin_cmdlist.
{
list_add(&plugin_cmds.list, &plugin_cmdlist);
return 0;
}
| static int add_pid | ( | int | patfd, |
| int | pid | ||
| ) | [static] |
Definition at line 120 of file plugin_getsid.c.
References dprintf0.
Referenced by start().
{
struct dmx_sct_filter_params sct_filter;
bzero(&sct_filter, sizeof(struct dmx_sct_filter_params));
sct_filter.pid = (__u16) pid;
sct_filter.flags = DMX_IMMEDIATE_START;
if(ioctl(patfd, DMX_SET_BUFFER_SIZE, 0x40000) < 0) {
dprintf0("Failed to set buffersize on fd:%d, pid:%d (err:%d)\n",
patfd,pid, errno);
return 1;
}
if (ioctl(patfd, DMX_SET_FILTER, &sct_filter) < 0) {
dprintf0("Failed to set filter on fd:%d pid:%d (err: %d)\n",
patfd, pid, errno);
return 1;
}
return 0;
}
| static int check_av | ( | unsigned char | type | ) | [static] |
Definition at line 628 of file plugin_getsid.c.
References AACAudio, AC3Audio, DTSAudio, H222_1, H264Video, MHEG, MPEG1Audio, MPEG1Video, MPEG2Audio, MPEG2AudioAmd1, MPEG2Video, MPEG4Video, and OpenCableVideo.
Referenced by find_pid().
{
switch(type) {
case MPEG1Video:
case MPEG2Video:
case MPEG4Video:
case H264Video:
case OpenCableVideo:
return 1;
case MPEG1Audio:
case MPEG2Audio:
case MPEG2AudioAmd1:
case AACAudio:
case AC3Audio:
case DTSAudio:
return 1;
case MHEG:
case H222_1:
return 1;
default:
return 0;
}
return 0;
}
| static void clear_sid_data | ( | struct sid_data * | sid_data | ) | [static] |
Definition at line 763 of file plugin_getsid.c.
References dmxcmd::checked, sid_data::cmdqueue, sid_data::common, sid_data::cond, free_sid(), sid_data::has_map, sid::list, list_del(), list_empty(), list_entry, list_for_each, list_head::next, NULL, common_data::real_adapt, dmxcmd::sid, and sid_data::sidlist.
Referenced by fe_tune(), and set_demux().
{
int adapt;
struct sid *sid_ll;
struct dmxcmd *dmxcmd;
adapt = sid_data->common->real_adapt;
while(! list_empty(&sid_data->sidlist)) {
sid_ll = list_entry(sid_data->sidlist.next, struct sid);
list_del(&sid_ll->list);
free_sid(sid_ll);
}
//reset queued pids
{
struct list_head *lptr;
list_for_each(lptr, &sid_data->cmdqueue) {
dmxcmd = list_entry(lptr, struct dmxcmd);
dmxcmd->checked = 0;
dmxcmd->sid = NULL;
}
}
//force a rescan of pmts
sid_data->has_map = 0;
pthread_cond_signal(&sid_data->cond);
}
| static void close_demux | ( | struct parser_cmds * | pc, |
| struct poll_ll * | fdptr, | ||
| cmdret_t * | result, | ||
| int * | ret, | ||
| unsigned long int | cmd, | ||
| unsigned char * | data | ||
| ) | [static] |
Definition at line 887 of file plugin_getsid.c.
References dmxcmd::checked, sid_data::cmdqueue, sid_data::common, poll_ll::fd, fd, find_siddata_from_pc(), dmxcmd::list, list_add_l, list_del(), list_lock, ll_find_elem, MSG_LOW_PRIORITY, MSG_REMOVESID, msg_send, sid_data::mutex, NULL, common_data::real_adapt, sid_data::removed_sid, sid::sid, and dmxcmd::sid.
Referenced by connect_sid().
{
struct sid_data *sid_data;
struct dmxcmd *dmxcmd, *tmpdmx;
sid_data = find_siddata_from_pc(pc);
if(sid_data == NULL)
return;
pthread_mutex_lock(&sid_data->mutex);
//if(sid_data->sendmsg)
//remove only GETSID on this demux!
//msg_remove_type_from_list(MSG_LOW_PRIORITY, MSG_ADDSID, free_addsid_msg);
//removed this fd from the cmdqueue
ll_find_elem(dmxcmd, sid_data->cmdqueue, fd, fdptr->fd, struct dmxcmd);
if(dmxcmd) {
list_del(&dmxcmd->list);
if(dmxcmd->checked && dmxcmd->sid) {
msg_send(MSG_LOW_PRIORITY, MSG_REMOVESID, sid_data->common->real_adapt,
(void *)(dmxcmd->sid->sid));
//check that this sid is no longer being viewed
ll_find_elem(tmpdmx, sid_data->cmdqueue, sid, dmxcmd->sid, struct dmxcmd);
if(! tmpdmx) {
sid_data->removed_sid = 1;
}
}
list_add_l(&dmxcmd->list, &dmxcmd_empty_queue, &list_lock);
}
pthread_mutex_unlock(&sid_data->mutex);
}
| static bool cmp_wild | ( | const char * | pat, |
| const char * | s | ||
| ) | [static] |
Definition at line 319 of file plugin_getsid.c.
Referenced by match_sid().
| static void connect_sid | ( | struct parser_adpt * | pc_all | ) | [static] |
Definition at line 975 of file plugin_getsid.c.
References ATTACH_CALLBACK, close_demux(), sid_data::cmdqueue, parser_cmds::common, sid_data::common, sid_data::cond, parser_adpt::demux, fe_close(), fe_tune(), parser_adpt::frontend, sid_data::has_map, INIT_LIST_HEAD, sid_data::list, list_add_tail(), sid_data::mutex, NULL, opt_experimental, parser_cmds::post_close, parser_cmds::post_ioctl, parser_cmds::pre_ioctl, sid_data::sendmsg, set_demux(), and sid_data::sidlist.
{
struct sid_data *sid_data;
sid_data = (struct sid_data *)malloc(sizeof(struct sid_data));
if(! sid_data)
return;
bzero(sid_data, sizeof(struct sid_data));
//these shouldn't be needed
sid_data->sendmsg = 0;
sid_data->has_map = 0;
sid_data->common = pc_all->frontend->common;
pthread_mutex_init(&sid_data->mutex, NULL);
pthread_cond_init(&sid_data->cond, NULL);
INIT_LIST_HEAD(&sid_data->sidlist);
INIT_LIST_HEAD(&sid_data->cmdqueue);
if(opt_experimental) {
ATTACH_CALLBACK(&pc_all->frontend->pre_ioctl, fe_tune, -1);
} else {
ATTACH_CALLBACK(&pc_all->frontend->post_ioctl, fe_tune, -1);
}
ATTACH_CALLBACK(&pc_all->frontend->post_close, fe_close, -1);
ATTACH_CALLBACK(&pc_all->demux->post_ioctl, set_demux, -1);
ATTACH_CALLBACK(&pc_all->demux->post_close, close_demux, -1);
list_add_tail(&sid_data->list, &getsidlist);
}
| static void enable_msg | ( | struct parser_cmds * | pc, |
| int | enable | ||
| ) | [static] |
Definition at line 968 of file plugin_getsid.c.
References find_siddata_from_pc(), and sid_data::sendmsg.
{
struct sid_data *sid_data = find_siddata_from_pc(pc);
if(sid_data)
sid_data->sendmsg = enable;
}
| static void fe_close | ( | struct parser_cmds * | pc, |
| struct poll_ll * | fdptr, | ||
| cmdret_t * | result, | ||
| int * | ret, | ||
| unsigned long int | cmd, | ||
| unsigned char * | data | ||
| ) | [static] |
Definition at line 857 of file plugin_getsid.c.
References sid_data::common, find_siddata_from_pc(), poll_ll::flags, free_addsid_msg(), MSG_ADDSID, MSG_LOW_PRIORITY, msg_remove_type_from_list(), MSG_REMOVESID, MSG_RESETSID, msg_send, sid_data::mutex, NULL, common_data::real_adapt, and sid_data::sendmsg.
Referenced by connect_sid().
{
struct sid_data *sid_data;
int adapt;
sid_data = find_siddata_from_pc(pc);
adapt = sid_data->common->real_adapt;
if(sid_data == NULL)
return;
if((fdptr->flags & O_ACCMODE) == O_RDONLY)
return;
pthread_mutex_lock(&sid_data->mutex);
if(sid_data->sendmsg) {
msg_remove_type_from_list(MSG_LOW_PRIORITY, MSG_ADDSID, adapt,
free_addsid_msg);
msg_remove_type_from_list(MSG_LOW_PRIORITY, MSG_REMOVESID, adapt, NULL);
msg_remove_type_from_list(MSG_LOW_PRIORITY, MSG_RESETSID, adapt, NULL);
}
msg_send(MSG_LOW_PRIORITY, MSG_RESETSID, adapt, NULL);
pthread_mutex_unlock(&sid_data->mutex);
}
| static void fe_tune | ( | struct parser_cmds * | pc, |
| struct poll_ll * | fdptr, | ||
| cmdret_t * | result, | ||
| int * | ret, | ||
| unsigned long int | cmd, | ||
| unsigned char * | data | ||
| ) | [static] |
Definition at line 792 of file plugin_getsid.c.
References clear_sid_data(), CMD_SKIPCALL, sid_data::common, dprintf0, FE_SET_FRONTEND2, find_siddata_from_pc(), free_addsid_msg(), MSG_ADDSID, MSG_LOW_PRIORITY, msg_remove_type_from_list(), MSG_REMOVESID, MSG_RESETSID, msg_send, sid_data::mutex, NULL, opt_experimental, common_data::real_adapt, sid_data::sendmsg, and sid_data::tunecache.
Referenced by connect_sid().
{
struct sid_data *sid_data;
int adapt;
sid_data = find_siddata_from_pc(pc);
adapt = sid_data->common->real_adapt;
if(sid_data == NULL)
return;
if(cmd == FE_SET_FRONTEND || cmd == FE_SET_FRONTEND2) {
dprintf0("Tuning frontend\n");
if(memcmp(&sid_data->tunecache, data, sizeof(struct dvb_frontend_parameters))) {
pthread_mutex_lock(&sid_data->mutex);
memcpy(&sid_data->tunecache, data, sizeof(struct dvb_frontend_parameters));
if(sid_data->sendmsg) {
msg_remove_type_from_list(MSG_LOW_PRIORITY, MSG_ADDSID, adapt,
free_addsid_msg);
msg_remove_type_from_list(MSG_LOW_PRIORITY, MSG_REMOVESID, adapt, NULL);
msg_remove_type_from_list(MSG_LOW_PRIORITY, MSG_RESETSID, adapt, NULL);
}
msg_send(MSG_LOW_PRIORITY, MSG_RESETSID, adapt, NULL);
clear_sid_data(sid_data);
pthread_mutex_unlock(&sid_data->mutex);
} else {
dprintf0("Skipping cache reset since tuning matches last tune\n");
if(opt_experimental)
*result = CMD_SKIPCALL;
}
#if DVB_API_VERSION >=5
} else if (cmd == FE_SET_PROPERTY) {
dprintf0("Tuning frontend (new)\n");
pthread_mutex_lock(&sid_data->mutex);
if(sid_data->sendmsg) {
msg_remove_type_from_list(MSG_LOW_PRIORITY, MSG_ADDSID, adapt,
free_addsid_msg);
msg_remove_type_from_list(MSG_LOW_PRIORITY, MSG_REMOVESID, adapt, NULL);
msg_remove_type_from_list(MSG_LOW_PRIORITY, MSG_RESETSID, adapt, NULL);
}
msg_send(MSG_LOW_PRIORITY, MSG_RESETSID, adapt, NULL);
clear_sid_data(sid_data);
pthread_mutex_unlock(&sid_data->mutex);
memset(&sid_data->tunecache, 0, sizeof(struct dvb_frontend_parameters));
#endif
} else if(cmd == FE_DISEQC_SEND_MASTER_CMD
|| cmd == FE_DISEQC_SEND_BURST
|| cmd == FE_SET_TONE
|| cmd == FE_SET_VOLTAGE
#ifdef FE_SET_STANDARD
|| cmd == FE_SET_STANDARD
#endif
#ifdef FE_DISHNETWORK_SEND_LEGACY_CMD
|| cmd == FE_DISHNETWORK_SEND_LEGACY_CMD
#endif
)
{
dprintf0("Clearing tuning cache due to switch cmd\n");
memset(&sid_data->tunecache, 0, sizeof(struct dvb_frontend_parameters));
}
}
Definition at line 652 of file plugin_getsid.c.
References check_av(), dprintf3, epid::epid, sid::epid, list_entry, list_for_each, NULL, opt_allpids, and epid::type.
Referenced by read_sid().
{
struct list_head *ptr, *ptr1;
struct sid *sid_ll;
struct epid *epid_ll;
list_for_each(ptr, sidlist) {
sid_ll = list_entry(ptr, struct sid);
list_for_each(ptr1, &sid_ll->epid) {
epid_ll = list_entry(ptr1, struct epid);
if(epid_ll->epid == pid) {
if(opt_allpids || check_av(epid_ll->type)) {
return sid_ll;
} else {
dprintf3("Skipping pid %d because type is %d\n", epid_ll->epid,
epid_ll->type);
return NULL;
}
}
}
}
return NULL;
}
| static struct sid_data* find_siddata_from_pc | ( | struct parser_cmds * | pc | ) | [static, read] |
Definition at line 752 of file plugin_getsid.c.
References parser_cmds::common, sid_data::common, list_entry, list_for_each, and NULL.
Referenced by close_demux(), enable_msg(), fe_close(), fe_tune(), and set_demux().
{
struct list_head *ptr;
list_for_each(ptr, &getsidlist) {
struct sid_data *sid_data = list_entry(ptr, struct sid_data);
if(sid_data->common == pc->common)
return sid_data;
}
return NULL;
}
| void free_addsid_msg | ( | void * | msg | ) |
Definition at line 115 of file plugin_getsid.c.
References free_sidmsg().
Referenced by fe_close(), and fe_tune().
{
struct sid_msg *sidmsg = (struct sid_msg *)msg;
free_sidmsg(sidmsg);
}
| static void free_pat | ( | struct pat * | pat | ) | [static] |
Definition at line 151 of file plugin_getsid.c.
References pat::dmx_filter_ll, filter::fd, sidnum::list, filter::list, list_add_l, list_del(), list_empty(), list_entry, list_lock, list_head::next, and filter::sids.
Referenced by start().
{
while(! list_empty(&pat->dmx_filter_ll)) {
struct filter *filt = list_entry(pat->dmx_filter_ll.next, struct filter);
list_del(&filt->list);
while(! list_empty(&filt->sids)) {
struct sidnum *sidnum = list_entry(filt->sids.next, struct sidnum);
list_del(&sidnum->list);
list_add_l(&sidnum->list, &sidnum_empty_queue, &list_lock);
}
if(filt->fd > 0) {
close(filt->fd);
}
list_add_l(&filt->list, &filt_empty_queue, &list_lock);
}
}
| static void free_sid | ( | struct sid * | sid_ll | ) | [static] |
Definition at line 139 of file plugin_getsid.c.
References sid::epid, sid::list, epid::list, list_add(), list_del(), list_empty(), list_entry, list_lock, and list_head::next.
Referenced by clear_sid_data(), read_pmt(), and read_sid().
| void free_sidmsg | ( | struct sid_msg * | sidmsg | ) |
Definition at line 111 of file plugin_getsid.c.
References sid_msg::list, list_add_l, and list_lock.
Referenced by free_addsid_msg(), and process_cam().
{
list_add_l(&sidmsg->list, &sidmsg_empty_queue, &list_lock);
}
| static void launch_sid | ( | ) | [static] |
Definition at line 1002 of file plugin_getsid.c.
References default_attr, list_entry, list_for_each, read_sid(), and sid_data::thread.
{
struct list_head *ptr;
list_for_each(ptr, &getsidlist) {
struct sid_data *sid_data = list_entry(ptr, struct sid_data);
pthread_create(&sid_data->thread, &default_attr, read_sid, sid_data);
}
}
| LIST_HEAD | ( | epid_empty_queue | ) |
| static LIST_HEAD | ( | getsidlist | ) | [static] |
| LIST_HEAD | ( | sid_empty_queue | ) |
| LIST_HEAD | ( | dmxcmd_empty_queue | ) |
| LIST_HEAD | ( | sidmsg_empty_queue | ) |
| LIST_HEAD | ( | sidnum_empty_queue | ) |
| LIST_HEAD | ( | filt_empty_queue | ) |
| static bool match_sid | ( | int | sid, |
| const char * | param | ||
| ) | [static] |
Definition at line 328 of file plugin_getsid.c.
References cmp_wild(), and free.
Referenced by read_pmt().
| unsigned char* parse_ca | ( | unsigned char * | buf, |
| unsigned char * | ca, | ||
| int | len | ||
| ) |
Definition at line 249 of file plugin_getsid.c.
Referenced by read_pmt().
| static struct option* parseopt_sid | ( | arg_enum_t | cmd | ) | [static, read] |
Definition at line 1033 of file plugin_getsid.c.
References ARG_HELP, ARG_INIT, MAX_SIMULTANEOUS_PMT, NULL, opt_allpids, opt_experimental, opt_ignore, opt_maxfilters, opt_maxrestart, opt_orbit, opt_resetpidmap, opt_unseen, sid_opt, and Sid_Opts.
{
if(cmd == ARG_INIT) {
return Sid_Opts;
}
if(cmd == ARG_HELP) {
printf(" --sid-filt <num> : Maximum number of open filters (default 2)\n");
printf(" --sid-allpid : Parse all pids instead of just A/V\n");
printf(" --sid-ignore <sid1,sid2,...>\n");
printf(" : When tuning, ignore given SIDs\n");
printf(" --sid-unseen <sid1,sid2,...>\n");
printf(" : When tuning, treat given SIDs as unseen allways\n");
printf(" --sid-nocache : Don't cache pid<->sid mapping\n");
printf(" --sid-orbit <val> : Set the satellit orbit to 'val' and don't scan the NIT\n");
printf(" --sid-experimental: Enable experimental tuning code\n");
printf(" --sid-restart <n> : Max number of PAT/NIT read restarts\n");
}
if(! sid_opt)
return NULL;
switch(sid_opt) {
case 'f':
opt_maxfilters = atoi(optarg);
if (opt_maxfilters < 1)
opt_maxfilters = 1;
else if (opt_maxfilters > MAX_SIMULTANEOUS_PMT)
opt_maxfilters = MAX_SIMULTANEOUS_PMT;
break;
case 'p':
opt_allpids = 1;
break;
case 'o':
opt_orbit = strtol(optarg, NULL, 0);
break;
case 'c':
opt_resetpidmap = 1;
break;
case 'e':
opt_experimental = 1;
break;
case 'i':
opt_ignore = optarg;
break;
case 'u':
opt_unseen = optarg;
break;
case 'r':
opt_maxrestart = atoi(optarg);
break;
}
//must reset sid_opt after every call
sid_opt = 0;
return NULL;
}
| static int read_nit | ( | unsigned char * | buf, |
| struct nit_data * | nit, | ||
| unsigned int | size | ||
| ) | [static] |
Definition at line 270 of file plugin_getsid.c.
References dprintf0, nit_data::fec, nit_data::frequency, nit_data::is_east, nit_data::modulation, nit_data::orbit, nit_data::polarization, nit_data::symbolrate, and nit_data::type.
Referenced by start().
{
int len, tsl_len, td_len, tag_len, network_desc_len;
int network_id, pos, tag;
if (buf[0] != 0x40 && buf[0] != 0x41 && buf[0] != 0x72) {
dprintf0(
"read_nit expected table 0x40 or 0x41 but got 0x%02x\n", buf[0]);
return -1;
}
if (buf[0] != 0x40) {
return 0;
}
len = ((buf[1] & 0x07) << 8) | buf[2];
network_id = (buf[3]<<8) | buf[4];
network_desc_len = ((buf[8] & 0x0f) << 8) | buf[9];
tsl_len = ((buf[10+network_desc_len] & 0x0f) << 8) | buf[11+network_desc_len];
pos = 12+network_desc_len;
while (pos-network_desc_len-12 < tsl_len - 6 && pos < len - 3) {
td_len = ((buf[pos+4] & 0x0f) << 8) | buf[pos+5];
while (td_len > 0) {
tag = buf[pos+6];
tag_len = buf[pos+7];
if(tag == 0x43 && tag_len >= 11) { //satellite descriptor
nit->type = tag;
nit->frequency = (buf[pos+8] << 24) | (buf[pos+9]<<16) | (buf[pos+10]<<8) | buf[pos+11];
nit->orbit = (buf[pos+12] << 8) | buf[pos+13];
nit->is_east = buf[pos+14] >> 7;
nit->polarization = (buf[pos+14] >> 5) & 0x03;
nit->modulation = buf[pos+14] & 0x1f;
nit->symbolrate = (buf[pos+15]<<16) | (buf[pos+16]<<8) | buf[pos+17];
nit->fec = buf[pos+18];
printf("Orbit: %08x%c\n", nit->orbit, nit->is_east ? 'E' : 'W');
return 1;
} else if(tag == 0x44 && tag_len >= 11) { //cable descriptor
nit->type = tag;
nit->frequency = (buf[pos+8] << 24) | (buf[pos+9]<<16) | (buf[pos+10]<<8) | buf[pos+11];
nit->modulation = buf[pos+14];
nit->symbolrate = (buf[pos+15]<<16) | (buf[pos+16]<<8) | buf[pos+17];
nit->fec = buf[pos+18];
printf("Cable: %08x\n", nit->frequency);
return 1;
}
pos += tag_len+2;
td_len -= tag_len+2;
}
pos += 6;
}
return 0;
}
| static int read_pat | ( | unsigned char * | pes, |
| struct pat * | pat, | ||
| unsigned int | size | ||
| ) | [static] |
Definition at line 168 of file plugin_getsid.c.
References pat::dmx_filter_ll, dprintf0, dprintf2, pat::has_nit, INIT_LIST_HEAD, pat::last_section, sidnum::list, filter::list, list_add(), list_add_l, list_del(), list_empty(), list_entry, list_lock, ll_find_elem, MAX_PAT_SECTIONS, list_head::next, filter::pid, pop_entry_from_queue_l, pat::section_seen, sidnum::seen, sidnum::sid, sid, filter::sids, pat::version, and version.
Referenced by start().
{
unsigned int sec, end;
int version;
unsigned char *ptr, last_sec;
struct sidnum *sidnum;
if (pes[0] != 0x00) {
dprintf0(
"read_pat: expected PAT table 0x00 but got 0x%02x\n", pes[0]);
return 1;
}
end = (((pes[1] & 0x03) << 8 | pes[2]) + 3 - 4);
if(end > size-4) {
dprintf0("read_pat: invalid PAT table size (%d > %d)\n", end, size-4);
return 1;
}
version = (pes[5] >> 1) & 0x1f;
sec = pes[6];
last_sec = pes[7];
if(last_sec >= MAX_PAT_SECTIONS) {
dprintf0("read_pat: illegal section count %d > %d\n",
last_sec, MAX_PAT_SECTIONS);
return 1;
}
if (pat->version != version || last_sec != pat->last_section) {
pat->version = version;
pat->last_section = last_sec;
while(! list_empty(&pat->dmx_filter_ll)) {
struct filter *filt = list_entry(pat->dmx_filter_ll.next, struct filter);
list_del(&filt->list);
while(! list_empty(&filt->sids)) {
sidnum = list_entry(filt->sids.next, struct sidnum);
list_del(&sidnum->list);
list_add_l(&sidnum->list, &sidnum_empty_queue, &list_lock);
}
list_add_l(&filt->list, &filt_empty_queue, &list_lock);
}
}
if(pat->section_seen[sec])
return 0;
pat->section_seen[sec] = 1;
for(ptr = pes + 8; ptr < pes + end; ptr += 4) {
int sid, pid;
struct filter *filt;
sid = (ptr[0] << 8) | ptr[1];
pid = ((ptr[2] & 0x1F) << 8) | ptr[3];
if(sid != 0) {
dprintf2("found PID: %d for sid: %d\n", pid, sid);
ll_find_elem(filt, pat->dmx_filter_ll, pid, pid, struct filter);
if(! filt) {
pop_entry_from_queue_l(filt, &filt_empty_queue, struct filter,
&list_lock);
bzero(filt, sizeof(struct filter));
INIT_LIST_HEAD(&filt->sids);
list_add(&filt->list, &pat->dmx_filter_ll);
filt->pid = pid;
}
pop_entry_from_queue_l(sidnum, &sidnum_empty_queue, struct sidnum,
&list_lock);
sidnum->sid = sid;
sidnum->seen = 0;
list_add(&sidnum->list, &filt->sids);
} else {
pat->has_nit = pid;
dprintf2("found NIT at PID: %d", pid);
}
}
return 0;
}
| static int read_pmt | ( | unsigned char * | buf, |
| struct filter * | filt, | ||
| struct sid_data * | sid_data, | ||
| unsigned int | size | ||
| ) | [static] |
Definition at line 349 of file plugin_getsid.c.
References sid::ca, sid::calen, count, dprintf0, dprintf1, dprintf3, epid::epid, sid::epid, free_sid(), sid_data::has_map, INIT_LIST_HEAD, sid::list, epid::list, list_add(), list_add_tail(), list_lock, ll_find_elem, match_sid(), sid_data::mutex, NULL, opt_ignore, opt_unseen, parse_ca(), pop_entry_from_queue_l, sidnum::seen, sid::sid, sid, sid_data::sidlist, filter::sids, and epid::type.
Referenced by start().
{
//
// NOTE we aren't using last_sec here yet!
//
struct sid *sid_ll;
struct epid *epid_ll;
struct sidnum *sidnum;
unsigned char *captr;
unsigned int count, skip, pos;
int sid, sec, last_sec, pcrpid, epid, type;
if (buf[0] != 0x02) {
dprintf0(
"read_pmt expected table 0x02 but got 0x%02x\n", buf[0]);
return -1;
}
count = (((buf[1] & 0x03) << 8) | buf[2]) + 3 - 4;
sid = (buf[3] << 8) | buf[4];
sec = buf[6];
last_sec = buf[7];
pcrpid = ((buf[8] & 0x1F) << 8) | buf[9];
skip = ((buf[10] & 0x03) << 8) | buf[11];
if(skip > count - 12 || count > size) {
dprintf0("skip: %d > count: %d - 12 || count > size: %d\n",
skip, count, size);
return -1;
}
pop_entry_from_queue_l(sid_ll, &sid_empty_queue, struct sid, &list_lock);
INIT_LIST_HEAD(&sid_ll->epid);
captr = parse_ca(sid_ll->ca, buf + 12, skip);
if(captr == NULL) {
dprintf0("Bad CA found\n");
free_sid(sid_ll);
return -1;
}
dprintf3("read_pmt: sid: %d pcrpid: %d skip: %d count: %d\n", sid, pcrpid, skip, count);
ll_find_elem(sidnum, filt->sids, sid, sid, struct sidnum);
if(sidnum == NULL) {
dprintf1("Sid %d is unexpected\n", sid);
free_sid(sid_ll);
return -1;
}
if (match_sid(sid,opt_ignore)) {
dprintf0("Ignoring SID %d.\n", sid);
free_sid(sid_ll);
return -1;
}
if(sidnum->seen && !match_sid(sid,opt_unseen)) {
dprintf0("Already seen sid: %d\n", sid);
free_sid(sid_ll);
return -1;
}
sidnum->seen = 1;
sid_ll->sid = sid;
for(pos = 12 + skip; pos < count;) {
type = buf[pos];
epid = ((buf[pos+1] & 0x1F) << 8) | buf[pos+2];
skip = ((buf[pos+3] & 0x03) << 8) | buf[pos+4];
captr = parse_ca(captr, buf+pos+5, skip);
pop_entry_from_queue_l(epid_ll, &epid_empty_queue, struct epid, &list_lock);
epid_ll->epid = epid;
epid_ll->type = type;
list_add_tail(&epid_ll->list, &sid_ll->epid);
dprintf3("read_pmt: epid %d (type %d) mapped to sid %d\n", epid, type, sid);
pos += 5 + skip;
}
sid_ll->calen = captr - sid_ll->ca;
pthread_mutex_lock(&sid_data->mutex);
if(! sid_data->has_map) {
pthread_mutex_unlock(&sid_data->mutex);
free_sid(sid_ll);
return -1;
}
list_add(&sid_ll->list, &sid_data->sidlist);
pthread_mutex_unlock(&sid_data->mutex);
return 0;
}
| static void* read_sid | ( | void * | arg | ) | [static] |
Definition at line 673 of file plugin_getsid.c.
References sid::ca, sid_msg::ca, sid::calen, sid_msg::calen, dmxcmd::checked, sid_data::cmdqueue, sid_data::common, sid_data::cond, count, dprintf0, dprintf1, dprintf2, sid_msg::epid, sid::epid, epid::epid, sid_msg::epid_count, sid_msg::epidtype, dmxcmd::fd, find_pid(), free_sid(), sid_data::has_map, sid::list, list_del(), list_empty(), list_entry, list_for_each, list_lock, ll_find_elem, MSG_ADDSID, MSG_LOW_PRIORITY, msg_send, sid_data::mutex, list_head::next, sid_data::nit, sid_msg::nit, NULL, dmxcmd::pid, pop_entry_from_queue_l, common_data::real_adapt, sid_data::sendmsg, sid_msg::sid, sid::sid, dmxcmd::sid, sid_data::sidlist, start(), and epid::type.
Referenced by launch_sid().
{
struct sid_data *sid_data = (struct sid_data *)arg;
struct sid *sid_ll;
struct dmxcmd *dmxcmd;
char dmxdev[256];
int ret;
sprintf(dmxdev, "/dev/dvb/adapter%d/demux0", sid_data->common->real_adapt);
pthread_mutex_lock(&sid_data->mutex);
while(1) {
while(1) {
ll_find_elem(dmxcmd, sid_data->cmdqueue, checked, 0, struct dmxcmd);
if(dmxcmd) {
break;
}
pthread_cond_wait(&sid_data->cond, &sid_data->mutex);
}
//pop_entry_from_queue_l(dmxcmd, &sid_data->cmdqueue, struct dmxcmd,
// &list_lock);
//dmxcmd_stored = 0;
if(dmxcmd->fd == -1 && dmxcmd->sid == 0 && dmxcmd->sid == NULL)
return NULL;
if(! sid_data->has_map) {
//Try to read pmt, use a short-timeout in case the lock
//hasn't happened yet
pthread_mutex_unlock(&sid_data->mutex);
dprintf2("Got Start!\n");
//set has_map first, since it could get invalidated...
sid_data->has_map = 1;
ret = start(dmxdev, sid_data, 200 /*ms*/);
dprintf2("returned: %d\n", ret);
if(ret)
usleep(200000); /*200ms*/
pthread_mutex_lock(&sid_data->mutex);
if(ret || sid_data->has_map == 0) {
sid_data->has_map = 0;
while(! list_empty(&sid_data->sidlist)) {
sid_ll = list_entry(sid_data->sidlist.next, struct sid);
list_del(&sid_ll->list);
free_sid(sid_ll);
}
}
//We skip processing in case the dmx was closed while pmt parsing
continue;
}
dprintf2("Got Pid: %d\n", dmxcmd->pid);
dmxcmd->checked = 1;
if((sid_ll = find_pid(&sid_data->sidlist, dmxcmd->pid))) {
dprintf1("Found sid: %lu\n", sid_ll->sid);
dmxcmd->sid = sid_ll;
if (sid_data->sendmsg) {
struct list_head *lptr;
struct sid_msg *sidmsg;
struct epid *epid;
int count = 0;
//Duplicate dmxcmds to prevent a race
pop_entry_from_queue_l(sidmsg, &sidmsg_empty_queue, struct sid_msg,
&list_lock);
sidmsg->sid = dmxcmd->sid->sid;
sidmsg->calen = dmxcmd->sid->calen;
memcpy(sidmsg->ca, dmxcmd->sid->ca, dmxcmd->sid->calen);
list_for_each(lptr, &dmxcmd->sid->epid) {
epid = list_entry(lptr, struct epid);
sidmsg->epid[count] = epid->epid;
sidmsg->epidtype[count] = epid->type;
count++;
}
sidmsg->epid_count = count;
sidmsg->nit = sid_data->nit;
msg_send(MSG_LOW_PRIORITY, MSG_ADDSID, sid_data->common->real_adapt,
sidmsg);
} else {
dprintf0("Didn't find sid for pid: %d\n", dmxcmd->pid);
}
}
}
}
| static void set_demux | ( | struct parser_cmds * | pc, |
| struct poll_ll * | fdptr, | ||
| cmdret_t * | result, | ||
| int * | ret, | ||
| unsigned long int | cmd, | ||
| unsigned char * | data | ||
| ) | [static] |
Definition at line 921 of file plugin_getsid.c.
References dmxcmd::checked, clear_sid_data(), sid_data::cmdqueue, sid_data::common, sid_data::cond, dprintf1, dmxcmd::fd, poll_ll::fd, fd, find_siddata_from_pc(), dmxcmd::list, list_add_l, list_add_tail(), list_del(), list_lock, ll_find_elem, MSG_LOW_PRIORITY, MSG_REMOVESID, msg_send, sid_data::mutex, NULL, opt_resetpidmap, dmxcmd::pid, pop_entry_from_queue_l, common_data::real_adapt, sid_data::removed_sid, sid::sid, and dmxcmd::sid.
Referenced by connect_sid().
{
struct sid_data *sid_data;
struct dmxcmd *dmxcmd;
int pid;
sid_data = find_siddata_from_pc(pc);
if(sid_data == NULL)
return;
if(cmd == DMX_SET_PES_FILTER) {
pid = *(unsigned short *)data; //get pid from *filter_params
pthread_mutex_lock(&sid_data->mutex);
if(opt_resetpidmap && sid_data->removed_sid) {
sid_data->removed_sid = 0;
//NOTE: If this occurs while a 'ADD_SID' is in the message queue,
//then the message will be corrupted! We should deep-copy the epids
clear_sid_data(sid_data);
}
//Make sure we didn't just change pids on the same fd
ll_find_elem(dmxcmd, sid_data->cmdqueue, fd, fdptr->fd, struct dmxcmd);
if(dmxcmd) {
if(dmxcmd->sid)
msg_send(MSG_LOW_PRIORITY, MSG_REMOVESID, sid_data->common->real_adapt,
(void *)(dmxcmd->sid->sid));
list_del(&dmxcmd->list);
list_add_l(&dmxcmd->list, &dmxcmd_empty_queue, &list_lock);
}
pop_entry_from_queue_l(dmxcmd, &dmxcmd_empty_queue, struct dmxcmd,
&list_lock);
dmxcmd->pid = pid;
dmxcmd->fd = fdptr->fd;
dmxcmd->sid = NULL;
dmxcmd->checked = 0;
list_add_tail(&dmxcmd->list, &sid_data->cmdqueue);
dprintf1("Sending PID: %d\n", pid);
pthread_cond_signal(&sid_data->cond);
pthread_mutex_unlock(&sid_data->mutex);
}
}
| static void shutdown_sid | ( | ) | [static] |
Definition at line 1011 of file plugin_getsid.c.
References dmxcmd::checked, sid_data::cmdqueue, sid_data::cond, dmxcmd::fd, dmxcmd::list, list_add(), list_entry, list_for_each, list_lock, sid_data::mutex, NULL, dmxcmd::pid, pop_entry_from_queue_l, dmxcmd::sid, and sid_data::thread.
{
struct dmxcmd *dmxcmd;
struct list_head *ptr;
list_for_each(ptr, &getsidlist) {
struct sid_data *sid_data = list_entry(ptr, struct sid_data);
if(sid_data->thread) {
pthread_mutex_lock(&sid_data->mutex);
pop_entry_from_queue_l(dmxcmd, &dmxcmd_empty_queue, struct dmxcmd,
&list_lock);
dmxcmd->pid = 0;
dmxcmd->fd = -1; //Send a terminate command
dmxcmd->sid = NULL;
dmxcmd->checked = 0;
list_add(&dmxcmd->list, &sid_data->cmdqueue);
pthread_cond_signal(&sid_data->cond);
pthread_mutex_unlock(&sid_data->mutex);
pthread_join(sid_data->thread, NULL);
}
}
}
| static int start | ( | char * | dmxdev, |
| struct sid_data * | sid_data, | ||
| int | timeout | ||
| ) | [static] |
read_pat
Definition at line 431 of file plugin_getsid.c.
References add_pid(), count, pat::dmx_filter_ll, dprintf0, dprintf2, dprintf3, filter::fd, fd, free_pat(), sid_data::has_map, pat::has_nit, i, INIT_LIST_HEAD, list_empty(), list_entry, list_for_each, ll_find_elem, MAX_PAT_SECTIONS, sid_data::mutex, sid_data::nit, NULL, open(), opt_max_fail, opt_maxfilters, opt_maxrestart, opt_orbit, nit_data::orbit, filter::parse_err, pat::patfd, filter::pid, read_nit(), read_pat(), read_pmt(), pat::section_seen, sidnum::seen, filter::sids, and filter::used.
Referenced by cPlainKeys::Action(), cSmartCardViaccess::Decode(), dvblb_mmap(), forward_data(), cCardClient::ParseStdConfig(), cSystemCardClient::ProcessECM(), read_sid(), cEmuRom3Core::ReadHandler(), cTimer::Start(), and cSmartCardViaccess::Update().
{
unsigned char pes[4096];
struct pollfd pfd, pollfd[MAX_SIMULTANEOUS_PMT];
int pat_restart = 0, done = 0, size, i;
int ret;
struct pat pat;
struct list_head *lptr;
restart:
bzero(&pat, sizeof(struct pat));
INIT_LIST_HEAD(&pat.dmx_filter_ll);
pat.patfd = open(dmxdev, O_RDWR | O_NONBLOCK);
if(pat.patfd < 0) {
perror("start: open returned:");
free_pat(&pat);
return 1;
}
if(add_pid(pat.patfd, 0x00)) {
perror("start: failed to initialize pat demux:");
free_pat(&pat);
return 1;
}
pfd.fd = pat.patfd;
pfd.events = POLLIN;
pfd.revents = 0;
while(! done) {
if (poll(&pfd, 1, timeout) <= 0) continue;
if ((size = read(pat.patfd, pes, sizeof(pes))) < 0) {
dprintf0("start: pat read pes returned err: %d\n", errno);
perror("start: pat read pes returned");
close(pat.patfd);
free_pat(&pat);
return 1;
}
if(read_pat(pes, &pat, size)) {
close(pat.patfd);
free_pat(&pat);
return 1;
}
done = 1;
for (int i = 0; i < MAX_PAT_SECTIONS; i++) {
if(pat.section_seen == 0) {
done = 0;
break;
}
}
}
close(pat.patfd);
if(opt_orbit) {
sid_data->nit.orbit = opt_orbit;
pat.has_nit = 0;
}
if(pat.has_nit) {
int fd;
fd=open(dmxdev, O_RDWR | O_NONBLOCK);
if (fd <= 0) {
dprintf0("start: Failed to open demux device for NIT!\n");
perror("demux open failed:");
}
else if (add_pid(fd, pat.has_nit)) {
char str[80];
sprintf(str, "start: Failed to initialize NIT demux");
perror(str);
} else {
pfd.fd = fd;
pfd.events = POLLIN;
pfd.revents = 0;
done = 0;
int nit_retries = 0;
while(done <= 0) {
if (poll(&pfd, 1, timeout) <= 0) continue;
if ((size = read(fd, pes, sizeof(pes))) < 0) {
dprintf0("start: nit read pes returned err: %d\n", errno);
perror("start: nit read pes returned");
}
done = read_nit(pes, &sid_data->nit, size);
if (done <= 0)
nit_retries++;
if (nit_retries == 10) {
if(++pat_restart<=opt_maxrestart) {
dprintf0("start: giving up reading nit and restarting...\n");
close(fd);
free_pat(&pat);
done = 0;
goto restart;
}
dprintf0("start: giving up reading nit\n");
done = 1;
}
}
}
close(fd);
}
while(1) {
int num_filters = 0, found = 0;
ret = 0;
list_for_each(lptr, &pat.dmx_filter_ll) {
struct filter *filt = list_entry(lptr, struct filter);
if(filt->used) {
if(filt->fd >0) {
close(filt->fd);
filt->fd = -1;
}
continue;
}
filt->fd=open(dmxdev, O_RDWR | O_NONBLOCK);
if (filt->fd <= 0) {
dprintf0("start: Failed to open %dth demux device!\n", num_filters);
perror("demux open failed:");
ret = 1;
break;
}
if (add_pid(filt->fd, filt->pid)) {
char str[80];
sprintf(str, "start: Failed to initialize %dth pmt demux", num_filters);
perror(str);
close(filt->fd);
filt->fd = -1;
ret = 1;
break;
}
filt->used = 1;
num_filters++;
if(num_filters >= opt_maxfilters) {
ret = 1;
break;
}
}
if(! num_filters)
break;
dprintf2("Reading %d of %d filters\n", num_filters, opt_maxfilters);
while(found != num_filters) {
int count = 0;
list_for_each(lptr, &pat.dmx_filter_ll) {
struct filter *filt = list_entry(lptr, struct filter);
if (filt->used && filt->fd > 0 && ! list_empty(&filt->sids)) {
pollfd[count].fd=filt->fd;
pollfd[count].events = POLLIN;
pollfd[count].revents = 0;
count++;
}
}
dprintf3("polling %d fds\n", count);
poll(pollfd, count, timeout);
for(i = 0; i < count; i++) {
if(! (pollfd[i].revents & POLLIN))
continue;
// read pmt
while((size = read(pollfd[i].fd, pes, sizeof(pes))) >= 3) {
struct filter *filt;
dprintf3("Read %d bytes\n", size);
ll_find_elem(filt, pat.dmx_filter_ll, fd, pollfd[i].fd, struct filter);
int ret = read_pmt(pes, filt, sid_data, size);
if(ret < 0) {
filt->parse_err++;
if (filt->parse_err > opt_max_fail)
goto exit;
}
if(ret == 0) {
struct sidnum *sidnum;
filt->parse_err = 0;
ll_find_elem(sidnum, filt->sids, seen, 0, struct sidnum);
if(sidnum == NULL) {
found ++;
break;
}
} else {
pthread_mutex_lock(&sid_data->mutex);
ret = ! sid_data->has_map;
pthread_mutex_unlock(&sid_data->mutex);
if(ret)
goto exit;
}
}
}
pthread_mutex_lock(&sid_data->mutex);
ret = ! sid_data->has_map;
pthread_mutex_unlock(&sid_data->mutex);
if(ret)
goto exit;
}
}
exit:
free_pat(&pat);
return ret;
}
pthread_mutex_t list_lock = PTHREAD_MUTEX_INITIALIZER [static] |
Definition at line 103 of file plugin_getsid.c.
Referenced by close_demux(), free_pat(), free_sid(), free_sidmsg(), read_pat(), read_pmt(), read_sid(), set_demux(), and shutdown_sid().
int opt_allpids = 0 [static] |
Definition at line 84 of file plugin_getsid.c.
Referenced by find_pid(), and parseopt_sid().
int opt_experimental = 0 [static] |
Definition at line 86 of file plugin_getsid.c.
Referenced by connect_sid(), fe_tune(), and parseopt_sid().
char* opt_ignore = 0 [static] |
Definition at line 88 of file plugin_getsid.c.
Referenced by parseopt_sid(), and read_pmt().
int opt_max_fail = 20 [static] |
Definition at line 83 of file plugin_getsid.c.
Referenced by start().
int opt_maxfilters = 2 [static] |
Definition at line 82 of file plugin_getsid.c.
Referenced by parseopt_sid(), and start().
int opt_maxrestart = 0 [static] |
Definition at line 90 of file plugin_getsid.c.
Referenced by parseopt_sid(), and start().
int opt_orbit = 0 [static] |
Definition at line 87 of file plugin_getsid.c.
Referenced by parseopt_sid(), and start().
int opt_resetpidmap = 0 [static] |
Definition at line 85 of file plugin_getsid.c.
Referenced by parseopt_sid(), and set_demux().
char* opt_unseen = 0 [static] |
Definition at line 89 of file plugin_getsid.c.
Referenced by parseopt_sid(), and read_pmt().
struct plugin_cmd plugin_cmds [static] |
{{NULL, NULL}, PLUGIN_ID, "channel",
parseopt_sid, connect_sid, launch_sid, NULL, enable_msg,
shutdown_sid, NULL}
Definition at line 1089 of file plugin_getsid.c.
int sid_opt = 0 [static] |
Definition at line 81 of file plugin_getsid.c.
Referenced by parseopt_sid().
struct option Sid_Opts[] [static] |
{
{"sid-filt", 1, &sid_opt, 'f'},
{"sid-allpid", 0, &sid_opt, 'p'},
{"sid-nocache", 0, &sid_opt, 'c'},
{"sid-orbit", 1, &sid_opt, 'o'},
{"sid-experimental", 0, &sid_opt, 'e'},
{"sid-ignore", 1, &sid_opt, 'i'},
{"sid-restart", 1, &sid_opt, 'r'},
{"sid-unseen", 1, &sid_opt, 'u'},
{0, 0, 0, 0},
}
Definition at line 91 of file plugin_getsid.c.
Referenced by parseopt_sid().