SASC
DVBSoftCAM

plugin_showioctl.c

Go to the documentation of this file.
00001 /*
00002    DVBLoopback
00003    Copyright Alan Nisota 2006
00004 
00005    This file is part of DVBLoopback.
00006 
00007     DVBLoopback is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 2 of the License, or
00010     (at your option) any later version.
00011 
00012     DVBLoopback is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with DVBLoopback; if not, write to the Free Software
00019     Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00020 */
00021 #include <stdlib.h>
00022 #include <stdio.h>
00023 #include <fcntl.h>
00024 #include <pthread.h>
00025 #include <sys/mman.h>
00026 #include <sys/poll.h>
00027 #include <sys/ioctl.h>
00028 #include <signal.h>
00029 #include <string.h>
00030 #include <getopt.h>
00031 #include <unistd.h>
00032 #include "list.h"
00033 #include <linux/dvb/dmx.h>
00034 #include <linux/dvb/frontend.h>
00035 
00036 #include "plugin_getsid.h"
00037 #include "msg_passing.h"
00038 
00039 #define PLUGIN_ID 10
00040 #define DBG_NAME "IOCTL"
00041 #include "debug.h" //This is required to happen AFTER PLUGIN_ID is defined
00042 
00043 //Get rid of the usefless ioctl typechecking
00044 #ifdef _IOC_TYPECHECK
00045   #undef _IOC_TYPECHECK
00046   #define _IOC_TYPECHECK(t) (sizeof(t))
00047 #endif
00048 static void fe_ioctl(struct parser_cmds *pc, struct poll_ll *fdptr,
00049                     cmdret_t *result, int *ret,
00050                     unsigned long int cmd, unsigned char *data)
00051 {
00052     __u32 d32 = (*(unsigned long *)data) & 0xffffffff;
00053     __u16 d16 = d32 & 0xffff;
00054     char str[256], str1[80];;
00055     if(! ((_dbglvl >> DVBDBG_IOCTL) & 1))
00056       return;
00057     switch(cmd) {
00058       case FE_GET_INFO:
00059         {
00060           struct dvb_frontend_info *d = (struct dvb_frontend_info *)data;
00061           tmprintf("","FE_GET_INFO(%d): '%s'\n"
00062                  "min:%u max:%u step:%u tol:%u minsr:%u maxsr:%u tolsr:%u\n",
00063                  fdptr->fd, d->name, d->frequency_min, d->frequency_max,
00064                  d->frequency_stepsize, d->frequency_tolerance,
00065                  d->symbol_rate_min, d->symbol_rate_max,
00066                  d->symbol_rate_tolerance);
00067         }
00068         break;
00069       case FE_SET_TONE:
00070         tmprintf("","FE_SET_TONE(%d): %s\n", fdptr->fd, (d32 ==SEC_TONE_ON) ?
00071                "ON" : "OFF");
00072         break;
00073       case FE_SET_VOLTAGE:
00074         tmprintf("","FE_SET_VOLTAGE(%d): %s\n", fdptr->fd, (d32 ==SEC_VOLTAGE_13) ?
00075                "13" : (d32 == SEC_VOLTAGE_18 ? "18" : "OFF"));
00076         break;
00077       case FE_ENABLE_HIGH_LNB_VOLTAGE:
00078         tmprintf("","FE_ENABLE_HIGH_LNB_VOLTAGE:(%d): %d\n", fdptr->fd, d32);
00079         break;
00080       case FE_READ_STATUS:
00081         str[0] = 0;
00082         if(d32 & FE_HAS_SIGNAL)
00083           strcat(str," SIGNAL");
00084         if(d32 & FE_HAS_CARRIER)
00085           strcat(str," CARRIER");
00086         if(d32 & FE_HAS_VITERBI)
00087           strcat(str," VITERBI");
00088         if(d32 & FE_HAS_SYNC)
00089           strcat(str," SYNC");
00090         if(d32 & FE_HAS_LOCK)
00091           strcat(str," LOCK");
00092         if(d32 & FE_TIMEDOUT)
00093           strcat(str," TIMEDOUT");
00094         if(d32 & FE_REINIT)
00095           strcat(str," REINIT");
00096         tmprintf("","FE_READ_STATUS(%d):%s\n", fdptr->fd, str);
00097         break;
00098       case FE_READ_BER:
00099         tmprintf("","FE_READ_BER(%d): %u\n", fdptr->fd, d32);
00100         break;
00101       case FE_READ_SIGNAL_STRENGTH:
00102         tmprintf("","FE_READ_SIGNAL_STRENGTH(%d): %u\n", fdptr->fd, d16);
00103         break;
00104       case FE_READ_SNR:
00105         tmprintf("","FE_READ_SNR(%d): %u\n", fdptr->fd, d16);
00106         break;
00107       case FE_READ_UNCORRECTED_BLOCKS:
00108         tmprintf("","FE_READ_UNCORRECTED_BLOCKS(%d): %u\n", fdptr->fd, d32);
00109         break;
00110 #ifdef FE_SET_FRONTEND2
00111       case FE_SET_FRONTEND2:
00112         {
00113           struct dvb_frontend_parameters_new *fe =
00114                  (struct dvb_frontend_parameters_new *)data;
00115           tmprintf("","FE_SET_FRONTEND2(%d): freq: %d inv: %s\n"
00116                       "  QPSK: sr: %d fec: %d\n"
00117                       "  DVBS2: sr: %d fec: %d mod: %d rol: %d\n", fdptr->fd,
00118                 fe->frequency, (fe->inversion == INVERSION_OFF ? "OFF" :
00119                 (fe->inversion == INVERSION_ON ? "ON" : "AUTO")),
00120                 fe->u.qpsk.symbol_rate, fe->u.qpsk.fec_inner,
00121                 fe->u.qpsk2.symbol_rate, fe->u.qpsk2.fec_inner,
00122                 fe->u.qpsk2.modulation, fe->u.qpsk2.rolloff_factor);
00123         }
00124         break;
00125       case FE_GET_FRONTEND2:
00126         tmprintf("","FE_GET_FRONTEND2(%d)\n", fdptr->fd);
00127         break;
00128       case FE_SET_STANDARD:
00129         {
00130           char t[10];
00131           switch(d32) {
00132             case FE_QPSK:   strcpy(t, "QPSK"); break;
00133             case FE_QAM:    strcpy(t, "QAM"); break;
00134             case FE_OFDM:   strcpy(t, "OFDM"); break;
00135             case FE_ATSC:   strcpy(t, "ATSC"); break;
00136             case FE_DVB_S:  strcpy(t, "DVB_S"); break;
00137             case FE_DVB_C:  strcpy(t, "DVB_C"); break;
00138             case FE_DVB_T:  strcpy(t, "DVB_T"); break;
00139             case FE_DVB_S2: strcpy(t, "DVB_S2"); break;
00140             default: strcpy(t, "Unkown"); break;
00141           }
00142           tmprintf("","FE_SET_STANDARD(%d): %s\n", fdptr->fd, t);
00143         }
00144         break;
00145       case FE_GET_EXTENDED_INFO:
00146         tmprintf("","FE_GET_EXTENDED_INFO(%d)\n", fdptr->fd);
00147         break;
00148 #endif
00149       case FE_SET_FRONTEND:
00150         {
00151           struct dvb_frontend_parameters *fe =
00152                  (struct dvb_frontend_parameters *)data;
00153           tmprintf("","FE_SET_FRONTEND(%d): freq: %d inv: %s\n"
00154                       "  QPSK: sr: %d fec: %d\n", fdptr->fd,
00155                 fe->frequency, (fe->inversion == INVERSION_OFF ? "OFF" :
00156                 (fe->inversion == INVERSION_ON ? "ON" : "AUTO")),
00157                 fe->u.qpsk.symbol_rate, fe->u.qpsk.fec_inner);
00158         }
00159         break;
00160       case FE_GET_FRONTEND:
00161         tmprintf("","FE_GET_FRONTEND(%d)\n", fdptr->fd);
00162         break;
00163       case FE_GET_EVENT:
00164         {
00165           struct dvb_frontend_event *event =
00166                  (struct dvb_frontend_event *)data;
00167           str[0] = 0;
00168           if(*ret >= 0) {
00169             d32 = event->status;
00170             if(d32 & FE_HAS_SIGNAL)
00171               strcat(str," SIGNAL");
00172             if(d32 & FE_HAS_CARRIER)
00173               strcat(str," CARRIER");
00174             if(d32 & FE_HAS_VITERBI)
00175               strcat(str," VITERBI");
00176             if(d32 & FE_HAS_SYNC)
00177               strcat(str," SYNC");
00178             if(d32 & FE_HAS_LOCK)
00179               strcat(str," LOCK");
00180             if(d32 & FE_TIMEDOUT)
00181               strcat(str," TIMEDOUT");
00182             if(d32 & FE_REINIT)
00183               strcat(str," REINIT");
00184             strcat(str,"\n");
00185           }
00186           tmprintf("","FE_GET_EVENT(%d) returned %d\n%s", fdptr->fd, *ret, str);
00187         }
00188         break;
00189       case FE_DISEQC_SEND_MASTER_CMD:
00190         {
00191           struct dvb_diseqc_master_cmd *msg =
00192                                 (struct dvb_diseqc_master_cmd *)data;
00193           str[0] = 0;
00194           for(int i = 0; i < msg->msg_len; i++) {
00195             sprintf(str1," %02x", msg->msg[i]);
00196             strcat(str, str1);
00197           }
00198           tmprintf("","FE_DISEQC_SEND_MASTER_CMD(%d):%s\n", fdptr->fd, str);
00199         }
00200         break; 
00201 #ifdef FE_DISHNETWORK_SEND_LEGACY_CMD
00202       case FE_DISHNETWORK_SEND_LEGACY_CMD:
00203         {
00204           int s, p, c = d32 & 0x7f;
00205           switch(c) {
00206             case 0x34: s=21, p = 0; break;
00207             case 0x65: s=21, p = 1; break;
00208             case 0x46: s=42, p = 1; break;
00209             case 0x17: s=42, p = 1; break;
00210             case 0x39: s=64, p = 10; break;
00211             case 0x1a: s=64, p = 11; break;
00212             case 0x4b: s=64, p = 20; break;
00213             case 0x5c: s=64, p = 21; break;
00214             case 0x0d: s=64, p = 30; break;
00215             case 0x2e: s=64, p = 31; break;
00216             default: s=0; p=0; break;
00217           }
00218           tmprintf("","FE_DISHNETWORK_SEND_LEGACY_CMD(%d): SW%d p:%d\n", fdptr->fd,
00219                  s, p);
00220         }
00221         break;
00222 #endif
00223       default:
00224         break;
00225     }
00226 }
00227 static void demux_ioctl(struct parser_cmds *pc, struct poll_ll *fdptr,
00228                     cmdret_t *result, int *ret,
00229                     unsigned long int cmd, unsigned char *data)
00230 {
00231     char str[256], str1[80];
00232     __u32 d32 = (*(unsigned long *)data) & 0xffffffff;
00233     if(! ((_dbglvl >> DVBDBG_IOCTL) & 2))
00234       return;
00235     switch(cmd) {
00236       case DMX_START:
00237         tmprintf("","DMX_START(%d)\n", fdptr->fd);
00238         break;
00239       case DMX_STOP:
00240         tmprintf("","DMX_STOP(%d)\n", fdptr->fd);
00241         break;
00242       case DMX_SET_FILTER:
00243         {
00244           struct dmx_sct_filter_params *dmx =
00245                  (struct dmx_sct_filter_params *)data;
00246           str[0] = 0;
00247           if(dmx->flags)
00248             sprintf(str,"    flags: %s%s%s%s\n",
00249                    (dmx->flags & DMX_CHECK_CRC ? " CHECK_CRC" : ""),
00250                    (dmx->flags & DMX_ONESHOT ? " ONESHOT" : ""),
00251                    (dmx->flags & DMX_IMMEDIATE_START ? " IMMEDIATE_START" : ""),
00252                    (dmx->flags & DMX_KERNEL_CLIENT ? " KERNEL_CLIENT" : ""));
00253           for(int i = 0; i < DMX_FILTER_SIZE; i++) {
00254             if(dmx->filter.filter[i] == 0)
00255               break;
00256             sprintf(str1,"    filter: %02x mask: %02x mode: %02x\n",
00257                dmx->filter.filter[i], dmx->filter.mask[i],
00258                dmx->filter.mode[i]);
00259             strcat(str, str1);
00260           }
00261           tmprintf("","DMX_SET_FILTER(%d): pid:%d timeout:%d\n%s", fdptr->fd, 
00262                  dmx->pid, dmx->timeout, str);
00263         }
00264         break;
00265       case DMX_SET_PES_FILTER:
00266         {
00267           struct dmx_pes_filter_params *dmx =
00268                  (struct dmx_pes_filter_params *)data;
00269           char t[10];
00270           switch(dmx->pes_type) {
00271             case DMX_PES_AUDIO0: strcpy(t, "AUDIO"); break;
00272             case DMX_PES_VIDEO0: strcpy(t, "VIDEO"); break;
00273             case DMX_PES_TELETEXT0: strcpy(t, "TELETEXT"); break;
00274             case DMX_PES_SUBTITLE0: strcpy(t, "SUBTITLE"); break;
00275             case DMX_PES_PCR0: strcpy(t, "PCR"); break;
00276 
00277             case DMX_PES_AUDIO1: strcpy(t, "AUDIO1"); break;
00278             case DMX_PES_VIDEO1: strcpy(t, "VIDEO1"); break;
00279             case DMX_PES_TELETEXT1: strcpy(t, "TELETEXT1"); break;
00280             case DMX_PES_SUBTITLE1: strcpy(t, "SUBTITLE1"); break;
00281             case DMX_PES_PCR1: strcpy(t, "PCR1"); break;
00282 
00283             case DMX_PES_AUDIO2: strcpy(t, "AUDIO2"); break;
00284             case DMX_PES_VIDEO2: strcpy(t, "VIDEO2"); break;
00285             case DMX_PES_TELETEXT2: strcpy(t, "TELETEXT2"); break;
00286             case DMX_PES_SUBTITLE2: strcpy(t, "SUBTITLE2"); break;
00287             case DMX_PES_PCR2: strcpy(t, "PCR2"); break;
00288 
00289             case DMX_PES_AUDIO3: strcpy(t, "AUDIO3"); break;
00290             case DMX_PES_VIDEO3: strcpy(t, "VIDEO3"); break;
00291             case DMX_PES_TELETEXT3: strcpy(t, "TELETEXT3"); break;
00292             case DMX_PES_SUBTITLE3: strcpy(t, "SUBTITLE3"); break;
00293             case DMX_PES_PCR3: strcpy(t, "PCR3"); break;
00294 
00295             case DMX_PES_OTHER: strcpy(t, "OTHER"); break;
00296             default: strcpy(t, "Unknown"); break;
00297           }
00298           if(dmx->flags)
00299             sprintf(str,"    flags: %s%s%s%s\n",
00300                    (dmx->flags & DMX_CHECK_CRC ? " CHECK_CRC" : ""),
00301                    (dmx->flags & DMX_ONESHOT ? " ONESHOT" : ""),
00302                    (dmx->flags & DMX_IMMEDIATE_START ? " IMMEDIATE_START" : ""),
00303                    (dmx->flags & DMX_KERNEL_CLIENT ? " KERNEL_CLIENT" : ""));
00304           tmprintf("","DMX_SET_PES_FILTER(%d): pid:%d in:%s out:%s type:%s\n%s",
00305                  fdptr->fd, dmx->pid,
00306                  dmx->input == DMX_IN_FRONTEND ? "FRONTEND" : "DVR",
00307                  dmx->output == DMX_OUT_DECODER ? "DECODER" :
00308                      (dmx->output == DMX_OUT_TAP ? "TAP" : "TS_TAP"), t, str);
00309         }
00310         break;
00311       case DMX_SET_BUFFER_SIZE:
00312         tmprintf("","DMX_SET_BUFFER_SIZE(%d): %d\n", fdptr->fd, d32);
00313         break;
00314       case DMX_GET_PES_PIDS:
00315         {
00316           __u16 *pid = (__u16 *)data;
00317           str[0] = 0;
00318           for(int i = 0; i < 5; i++) {
00319             if(pid[i] <= 0)
00320               break;
00321             tmprintf(str1," %d", pid[i]);
00322             strcat(str, str1);
00323           }
00324           tmprintf("","DMX_GET_PES_PIDS(%d):%s\n", fdptr->fd, str);
00325         }
00326         break;
00327       case DMX_GET_CAPS:
00328         {
00329           struct dmx_caps *dmx = (struct dmx_caps*)data;
00330           tmprintf("","DMX_GET_CAPS(%d): %u num:%d\n", fdptr->fd, dmx->caps,
00331                  dmx->num_decoders);
00332         }
00333         break;
00334       case DMX_SET_SOURCE:
00335         tmprintf("","DMX_SET_SOURCE(%d): %d\n", fdptr->fd, d32);
00336         break;
00337       case DMX_GET_STC:
00338         tmprintf("","DMX_GET_STC(%d)\n", fdptr->fd);
00339         break;
00340     }
00341 }
00342 
00343 static void connect_imsg(struct parser_adpt *pc_all)
00344 {
00345   ATTACH_CALLBACK(&pc_all->frontend->post_ioctl, fe_ioctl,    -1);
00346   ATTACH_CALLBACK(&pc_all->demux->post_ioctl,    demux_ioctl, -1);
00347 }
00348 
00349 //list, plugin_id, name, parse_args, connect, launch, message, send_msg
00350 static struct plugin_cmd plugin_cmds = {{NULL, NULL}, PLUGIN_ID,
00351                        "ioctl debug",
00352                        NULL, connect_imsg, NULL, NULL, NULL, NULL, NULL};
00353 int __attribute__((constructor)) __showioctl_init(void)
00354 {
00355   list_add(&plugin_cmds.list, &plugin_cmdlist);
00356   return 0;
00357 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines