|
SASC
DVBSoftCAM
|
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 }