|
SASC
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 <sys/types.h>#include <sys/stat.h>#include <sys/wait.h>#include <signal.h>#include <string.h>#include <getopt.h>#include <unistd.h>#include <errno.h>#include "list.h"#include <linux/dvb/dmx.h>#include <linux/dvb/frontend.h>#include "process_req.h"#include "msg_passing.h"#include "plugin_getsid.h"#include "plugin_msg.h"#include "debug.h"Go to the source code of this file.
Classes | |
| struct | scanner |
Defines | |
| #define | PLUGIN_ID 30 |
| #define | DBG_NAME "Scanner" |
| #define | SCAN_MIN_WAITTIME (10) |
| #define | SCAN_WAITTIME (10*60) |
| #define | SCAN_TIMEOUT (30*60) |
| #define | SCAN_MIN_TUNETIME (10*60) |
| #define | SCAN_CAM_MINTIME 5 |
| #define | MAX_PORTS 16 |
| #define | FIND_CMD(result, adpt, type, _id) |
Functions | |
| static | LIST_HEAD (scanner_list) |
| char * | get_camdir () |
| static struct scanner * | find_scanner_from_pc (struct parser_cmds *pc) |
| void * | scan_loop (void *arg) |
| static void | process_scan (struct msg *msg, unsigned int priority) |
| static void | fe_open_pre (struct parser_cmds *pc, struct poll_ll *fdptr, cmdret_t *result, int *ret, unsigned long int cmd, unsigned char *data) |
| static void | fe_open_post (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 | launch_scan () |
| static void | connect_scan (struct parser_adpt *pc_all) |
| static struct option * | parseopt_scan (arg_enum_t cmd) |
| int | __attribute__ ((constructor)) |
Variables | |
| static int | scan_opt = 0 |
| static int | scan_ports = 0 |
| static struct option | Scan_Opts [] |
| static char | scan_script [256] |
| static char | scan_lib [256] |
| unsigned char | boo [1024] |
| static pthread_mutex_t | scanner_mutex = PTHREAD_MUTEX_INITIALIZER |
| static pthread_cond_t | scanner_cond = PTHREAD_COND_INITIALIZER |
| static pthread_t | scanner_thread |
| static struct plugin_cmd | plugin_cmds |
| #define DBG_NAME "Scanner" |
Definition at line 46 of file plugin_scan.c.
| #define FIND_CMD | ( | result, | |
| adpt, | |||
| type, | |||
| _id | |||
| ) |
do { \ struct cmd_list *cmd; \ ll_find_elem(cmd, adpt->pre_##type, id, (_id), struct cmd_list); \ if(! cmd) \ ll_find_elem(cmd, adpt->post_##type, id, (_id), struct cmd_list); \ if(! cmd) \ result = NULL;\ else \ result = cmd->cmd; \ } while(0);
Definition at line 296 of file plugin_scan.c.
| #define MAX_PORTS 16 |
Definition at line 70 of file plugin_scan.c.
| #define PLUGIN_ID 30 |
Definition at line 45 of file plugin_scan.c.
| #define SCAN_CAM_MINTIME 5 |
Definition at line 68 of file plugin_scan.c.
Referenced by process_scan().
| #define SCAN_MIN_TUNETIME (10*60) |
Definition at line 65 of file plugin_scan.c.
Referenced by scan_loop().
| #define SCAN_MIN_WAITTIME (10) |
Definition at line 58 of file plugin_scan.c.
Referenced by scan_loop().
| #define SCAN_TIMEOUT (30*60) |
Definition at line 62 of file plugin_scan.c.
Referenced by scan_loop().
| #define SCAN_WAITTIME (10*60) |
Definition at line 60 of file plugin_scan.c.
Referenced by scan_loop().
| int __attribute__ | ( | (constructor) | ) |
Definition at line 370 of file plugin_scan.c.
References plugin_cmd::list, list_add(), and plugin_cmdlist.
{
// communicates the existance of teh current plugin to the main program.
if(1) list_add(&plugin_cmds.list, &plugin_cmdlist);
return 0;
}
| static void connect_scan | ( | struct parser_adpt * | pc_all | ) | [static] |
Definition at line 316 of file plugin_scan.c.
References ATTACH_CALLBACK, dprintf0, fe_close(), fe_open_post(), fe_open_pre(), parser_adpt::frontend, get_camdir(), list_add_tail(), NULL, scanner::pc_all, parser_cmds::post_close, parser_cmds::post_open, parser_cmds::pre_open, scan_lib, scan_ports, and scan_script.
{
struct scanner *scanner;
struct stat st;
scanner = (struct scanner *)malloc(sizeof(struct scanner));
if(! scanner)
return;
bzero(scanner, sizeof(struct scanner));
if(scan_ports) {
snprintf(scan_script, sizeof(scan_script), "%s/scanner", get_camdir());
snprintf(scan_lib, sizeof(scan_lib), "%s/libscanwrap.so", get_camdir());
if(stat(scan_script, &st) == -1 || ! (st.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
dprintf0("Couldn't locate executable %s\n", scan_script);
exit(1);
}
if(stat(scan_lib, &st) == -1) {
dprintf0("Couldn't locate wrapper lib %s\n", scan_lib);
exit(1);
}
}
scanner->pc_all = pc_all;
scanner->lastcmd = time(NULL);
ATTACH_CALLBACK(&pc_all->frontend->pre_open, fe_open_pre, -1);
ATTACH_CALLBACK(&pc_all->frontend->post_open, fe_open_post, -1);
ATTACH_CALLBACK(&pc_all->frontend->post_close, fe_close, -1);
list_add_tail(&scanner->list, &scanner_list);
}
| 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 272 of file plugin_scan.c.
References scanner::fe_fdptr, scanner::fecount, find_scanner_from_pc(), poll_ll::flags, scanner::lastcmd, NULL, O_ASYNC, O_SYNC, and scanner_mutex.
Referenced by connect_scan().
{
struct scanner *scanner;
scanner = find_scanner_from_pc(pc);
if(scanner == NULL)
return;
if((fdptr->flags & O_ACCMODE) == O_RDONLY)
return;
pthread_mutex_lock(&scanner_mutex);
if((fdptr->flags & (O_SYNC | O_ASYNC)) == (O_SYNC | O_ASYNC)) {
// This is the scanner fd
scanner->fe_fdptr = NULL;
} else {
if(scanner->fecount > 0)
scanner->fecount--;
scanner->lastcmd = time(NULL);
}
pthread_mutex_unlock(&scanner_mutex);
}
| static void fe_open_post | ( | struct parser_cmds * | pc, |
| struct poll_ll * | fdptr, | ||
| cmdret_t * | result, | ||
| int * | ret, | ||
| unsigned long int | cmd, | ||
| unsigned char * | data | ||
| ) | [static] |
Definition at line 248 of file plugin_scan.c.
References poll_ll::fd, scanner::fe_fdptr, scanner::fecount, find_scanner_from_pc(), poll_ll::flags, scanner::lastcmd, NULL, O_ASYNC, O_SYNC, and scanner_mutex.
Referenced by connect_scan().
{
struct scanner *scanner;
scanner = find_scanner_from_pc(pc);
if(scanner == NULL)
return;
if((fdptr->flags & O_ACCMODE) == O_RDONLY)
return;
if(fdptr->fd < 0)
return;
pthread_mutex_lock(&scanner_mutex);
if((fdptr->flags & (O_SYNC | O_ASYNC)) == (O_SYNC | O_ASYNC)) {
// This is the scanner fd
scanner->fe_fdptr = fdptr;
} else {
scanner->fecount++;
scanner->lastcmd = time(NULL);
}
pthread_mutex_unlock(&scanner_mutex);
}
| static void fe_open_pre | ( | struct parser_cmds * | pc, |
| struct poll_ll * | fdptr, | ||
| cmdret_t * | result, | ||
| int * | ret, | ||
| unsigned long int | cmd, | ||
| unsigned char * | data | ||
| ) | [static] |
Definition at line 219 of file plugin_scan.c.
References poll_ll::fd, scanner::fe_fdptr, find_scanner_from_pc(), poll_ll::flags, scanner::lastcmd, NULL, O_ASYNC, O_SYNC, open(), scanner::pid, scanner_mutex, and scanner::waiting.
Referenced by connect_scan().
{
struct scanner *scanner;
scanner = find_scanner_from_pc(pc);
if(scanner == NULL)
return;
if((fdptr->flags & O_ACCMODE) == O_RDONLY)
return;
pthread_mutex_lock(&scanner_mutex);
if(scanner->fe_fdptr) {
if((fdptr->flags & (O_SYNC | O_ASYNC)) != (O_SYNC | O_ASYNC)) {
//This isn't the scanner fd so kill the scanner
if(scanner->pid && ! scanner->waiting) {
kill(scanner->pid, 9);
scanner->waiting = 1;
}
close(scanner->fe_fdptr->fd);
scanner->fe_fdptr->fd = open("/dev/null", O_RDWR);
scanner->fe_fdptr = NULL;
scanner->lastcmd = time(NULL);
}
}
pthread_mutex_unlock(&scanner_mutex);
}
| static struct scanner* find_scanner_from_pc | ( | struct parser_cmds * | pc | ) | [static, read] |
Definition at line 100 of file plugin_scan.c.
References parser_cmds::common, parser_adpt::frontend, list_entry, list_for_each, NULL, and scanner::pc_all.
Referenced by fe_close(), fe_open_post(), and fe_open_pre().
{
struct list_head *ptr;
list_for_each(ptr, &scanner_list) {
struct scanner *scanner = list_entry(ptr, struct scanner);
if(scanner->pc_all->frontend->common == pc->common)
return scanner;
}
return NULL;
}
| char* get_camdir | ( | ) |
Definition at line 44 of file plugin_cam.c.
References opt_camdir.
Referenced by connect_scan().
{ return opt_camdir;}
| static void launch_scan | ( | ) | [static] |
Definition at line 307 of file plugin_scan.c.
References default_attr, MSG_LOW_PRIORITY, MSG_RECURRING, msg_send_replace(), MSG_TRYSCAN, NULL, scan_loop(), scan_ports, and scanner_thread.
{
if(scan_ports) {
pthread_create(&scanner_thread, &default_attr, scan_loop, NULL);
msg_send_replace(MSG_LOW_PRIORITY, MSG_TRYSCAN, 0, NULL,
10, MSG_RECURRING);
}
}
| static LIST_HEAD | ( | scanner_list | ) | [static] |
| static struct option* parseopt_scan | ( | arg_enum_t | cmd | ) | [static, read] |
Definition at line 344 of file plugin_scan.c.
References ARG_HELP, ARG_INIT, dprintf0, NULL, scan_opt, Scan_Opts, and scan_ports.
{
if(cmd == ARG_INIT) {
return Scan_Opts;
}
if(cmd == ARG_HELP) {
printf(" --scan-ports <num_ports>: Turn on scanner\n");
}
if(! scan_opt)
return NULL;
switch(scan_opt) {
case 'p':
scan_ports = strtol(optarg, NULL, 0);
dprintf0("Enabling scanner on %d ports\n", scan_ports);
break;
}
//must reset scan_opt after every call
scan_opt = 0;
return NULL;
}
| static void process_scan | ( | struct msg * | msg, |
| unsigned int | priority | ||
| ) | [static] |
Definition at line 182 of file plugin_scan.c.
References scanner::ca, parser_cmds::common, msg::data, scanner::done, dprintf0, parser_adpt::frontend, msg::id, scanner::last_pol, scanner::lasttime, ll_find_elem, MSG_CAMUPDATE, MSG_PROCESSED, MSG_TRYSCAN, NULL, scanner::pc_all, scanner::pid, SCAN_CAM_MINTIME, scanner_cond, scanner_mutex, scanner::state, msg::type, common_data::virt_adapt, and scanner::waiting.
{
if (msg->type == MSG_TRYSCAN) {
msg->type = MSG_PROCESSED;
pthread_mutex_lock(&scanner_mutex);
pthread_cond_signal(&scanner_cond);
pthread_mutex_unlock(&scanner_mutex);
} else if(msg->type == MSG_CAMUPDATE) {
struct scanner *scanner;
time_t curtime = time(NULL);
int idx = (((unsigned long)msg->data)& 0xff) >> 1;
int polarity = ((unsigned long)msg->data)& 0x01;
msg->type = MSG_PROCESSED;
ll_find_elem(scanner, scanner_list, pc_all->frontend->common->virt_adapt, msg->id, struct scanner);
if(scanner == NULL || ! scanner->pid || scanner->waiting)
return;
if(polarity != scanner->ca[idx].last_pol &&
curtime - scanner->ca[idx].lasttime > SCAN_CAM_MINTIME) {
if(scanner->ca[idx].state < 4)
scanner->ca[idx].state++;
if(scanner->ca[idx].state == 4) {
pthread_mutex_lock(&scanner_mutex);
scanner->done = 1;
pthread_mutex_unlock(&scanner_mutex);
}
} else {
pthread_mutex_lock(&scanner_mutex);
scanner->done = 0;
pthread_mutex_unlock(&scanner_mutex);
scanner->ca[idx].state = 0;
}
scanner->ca[idx].last_pol = polarity;
scanner->ca[idx].lasttime = curtime;
dprintf0("id:%d idx: %d state:%d pol:%d done:%d\n", msg->id, idx, scanner->ca[idx].state, polarity, scanner->done);
}
}
| void* scan_loop | ( | void * | arg | ) |
Definition at line 111 of file plugin_scan.c.
References b, scanner::ca, parser_cmds::common, scanner::done, dprintf0, fd, scanner::fecount, scanner::found, parser_adpt::frontend, i, scanner::lastcmd, scanner::lasttime, list_entry, list_for_each, NULL, open(), scanner::pc_all, scanner::pid, scanner::port, scan_lib, SCAN_MIN_TUNETIME, SCAN_MIN_WAITTIME, scan_ports, scan_script, SCAN_TIMEOUT, SCAN_WAITTIME, scanner_cond, scanner_mutex, scanner::starttime, scanner::state, common_data::virt_adapt, and scanner::waiting.
Referenced by launch_scan().
{
struct scanner *scanner;
struct list_head *ptr;
time_t curtime;
pthread_mutex_lock(&scanner_mutex);
while(1) {
int ok = 0;
while(! ok) {
curtime = time(NULL);
list_for_each(ptr, &scanner_list) {
scanner = list_entry(ptr, struct scanner);
if(scanner->fecount==0 && curtime - scanner->lastcmd >= SCAN_MIN_WAITTIME) {
ok = 1;
break;
}
}
if(! ok) {
pthread_cond_wait(&scanner_cond, &scanner_mutex);
}
}
//We can start the scanner if we get here
if(! scanner->pid) {
if(curtime > scanner->starttime[scanner->port] + SCAN_WAITTIME) {
//Time to try scanning the current port
scanner->done = 0;
for(int i = 0; i < 8; i++) {
scanner->ca[i].lasttime = curtime;
scanner->ca[i].state = 0;
}
dprintf0("Starting scanner on port %d\n", scanner->port);
if(0 == (scanner->pid = fork())) {
char env[256], *env1[3] = {env, (char *) 0};
struct { char a[8], b[8], c[8];} arg = {"scanner", "", ""};
char *arg1[] = {arg.a, arg.b, arg.c, (char *) 0};
snprintf(env,sizeof(env), "LD_PRELOAD=%s", scan_lib);
snprintf(arg.b, 8, "%d", scanner->pc_all->frontend->common->virt_adapt);
snprintf(arg.c, 8, "%d", scanner->port);
int fd = open("/dev/null", O_WRONLY);
while (dup2(fd, 1) < 0 && errno == EINTR)
;
while (dup2(fd, 2) < 0 && errno == EINTR)
;
while (close(fd) < 0 && errno == EINTR)
;
execve(scan_script, arg1, env1);
exit(0);
}
scanner->starttime[scanner->port] = curtime;
}
} else if(waitpid(scanner->pid, NULL, WNOHANG)) {
scanner->pid = 0;
scanner->port = (scanner->port+1) % scan_ports;
scanner->waiting = 0;
} else if(! scanner->waiting &&
( (scanner->done
&& (! scanner->found[scanner->port]
|| curtime > scanner->starttime[scanner->port] + SCAN_MIN_TUNETIME)
)
|| curtime > scanner->starttime[scanner->port] + SCAN_TIMEOUT
)) {
if(scanner->done) {
dprintf0("Scan complete for port %d. Terminating %d\n", scanner->port, scanner->pid);
scanner->found[scanner->port] = 1;
}
kill(scanner->pid, 9);
scanner->waiting = 1;
}
scanner->lastcmd = curtime;
}
}
| unsigned char boo[1024] |
Definition at line 95 of file plugin_scan.c.
struct plugin_cmd plugin_cmds [static] |
{{NULL, NULL}, PLUGIN_ID, "scanner",
parseopt_scan, connect_scan, launch_scan, process_scan, NULL, NULL, NULL}
Definition at line 367 of file plugin_scan.c.
| char scan_lib[256] |
Definition at line 74 of file plugin_scan.c.
Referenced by connect_scan(), and scan_loop().
int scan_opt = 0 [static] |
Definition at line 51 of file plugin_scan.c.
Referenced by parseopt_scan().
struct option Scan_Opts[] [static] |
{
{"scan-ports", 1, &scan_opt, 'p'},
{0, 0, 0, 0},
}
Definition at line 53 of file plugin_scan.c.
Referenced by parseopt_scan().
int scan_ports = 0 [static] |
Definition at line 52 of file plugin_scan.c.
Referenced by connect_scan(), launch_scan(), parseopt_scan(), and scan_loop().
char scan_script[256] [static] |
Definition at line 74 of file plugin_scan.c.
Referenced by connect_scan(), and scan_loop().
pthread_cond_t scanner_cond = PTHREAD_COND_INITIALIZER [static] |
Definition at line 97 of file plugin_scan.c.
Referenced by process_scan(), and scan_loop().
pthread_mutex_t scanner_mutex = PTHREAD_MUTEX_INITIALIZER [static] |
Definition at line 96 of file plugin_scan.c.
Referenced by fe_close(), fe_open_post(), fe_open_pre(), process_scan(), and scan_loop().
pthread_t scanner_thread [static] |
Definition at line 98 of file plugin_scan.c.
Referenced by launch_scan().