00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00026 #include "DVBSocketController.hh"
00027
00028
00029 #include <sstream>
00030 #include <senf/Utils/Exception.hh>
00031 #include <senf/Utils/Logger/Logger.hh>
00032 #include <senf/Utils/membind.hh>
00033 #include <senf/Utils/Console/ParsedCommand.hh>
00034 #include <boost/shared_ptr.hpp>
00035 #include "DVBProtocolWrapper.hh"
00036
00037 #define prefix_
00038
00039
00040 unsigned int senf::DVBSocketController::controllerNr(0);
00041
00042 senf::DVBSocketController::DVBSocketController(DVBFrontendHandle frontendHandle_,
00043 const Callback & cb_)
00044 : dir( this ),
00045 frontendHandle( frontendHandle_ ),
00046 type( frontendHandle.protocol().getInfo().type ),
00047 parser( type ),
00048 cb( cb_ ),
00049 sectionNr(1),
00050 pesNr(1),
00051 event( "senf::DVBSocketController::readEvent",
00052 senf::membind(&DVBSocketController::readEvent, this), frontendHandle,
00053 senf::scheduler::FdEvent::EV_PRIO, false )
00054 {
00055 initConsole();
00056 }
00057
00058 prefix_ senf::DVBSocketController::~DVBSocketController()
00059 {}
00060
00061 prefix_ senf::DVBDemuxSectionHandle
00062 senf::DVBSocketController::createDVBDemuxSectionHandle(int adapternumber, int demuxnumber,
00063 bool addToConsole)
00064 {
00065 DVBDemuxSectionHandle sectionHandle(adapternumber, demuxnumber);
00066 if (addToConsole)
00067 this->addToConsole(sectionHandle);
00068 return sectionHandle;
00069
00070 }
00071
00072 prefix_ senf::DVBDemuxPESHandle
00073 senf::DVBSocketController::createDVBDemuxPESHandle(int adapternumber, int demuxnumber,
00074 bool addToConsole)
00075 {
00076 DVBDemuxPESHandle pesHandle(adapternumber, demuxnumber);
00077 if (addToConsole)
00078 this->addToConsole(pesHandle);
00079 return pesHandle;
00080
00081 }
00082
00083 prefix_ void senf::DVBSocketController::addToConsole(senf::DVBDemuxSectionHandle sh)
00084 {
00085 boost::shared_ptr<DVBSectionProtocolWrapper> wrap(new DVBSectionProtocolWrapper(sh));
00086 sh.protocol().addWrapper(wrap);
00087 dir.node().add("section" + senf::str(sectionNr), wrap->dir);
00088 sectionNr++;
00089 }
00090
00091 prefix_ void senf::DVBSocketController::addToConsole(senf::DVBDemuxPESHandle sh)
00092 {
00093 boost::shared_ptr<DVBPESProtocolWrapper> wrap(new DVBPESProtocolWrapper(sh));
00094 sh.protocol().addWrapper(wrap);
00095 dir.node().add("pes"+ senf::str(pesNr), wrap->dir);
00096 pesNr++;
00097 }
00098
00099 prefix_ void senf::DVBSocketController::tuneToCMD(std::string const & input, std::string const & mode)
00100 {
00101 struct dvb_frontend_parameters frontend;
00102
00103
00104 if (input.find(":") == std::string::npos)
00105 {
00106 if (mode.c_str()[0]=='a')
00107 tuneTo(input);
00108 else
00109 tuneTo_sync(input);
00110 return;
00111 }
00112
00113 frontend = parser.getFrontendParam("foo:"+input);
00114
00115 if (mode.c_str()[0]=='a') {
00116 switch (type) {
00117 case FE_QPSK:
00118 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate,
00119 frontend.u.qpsk.fec_inner);
00120 break;
00121 case FE_QAM:
00122 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
00123 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
00124 break;
00125 case FE_OFDM:
00126 tuneDVB_T(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
00127 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
00128 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
00129 frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
00130 break;
00131 default:
00132 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
00133 }
00134 }
00135 else {
00136 switch (type) {
00137 case FE_QPSK:
00138 tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate,
00139 frontend.u.qpsk.fec_inner);
00140 break;
00141 case FE_QAM:
00142 tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
00143 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
00144 break;
00145 case FE_OFDM:
00146 tuneDVB_T_sync(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
00147 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
00148 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
00149 frontend.u.ofdm.guard_interval,
00150 frontend.u.ofdm.hierarchy_information);
00151 break;
00152 default:
00153 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
00154 }
00155 }
00156 }
00157
00158 prefix_ void senf::DVBSocketController::tuneTo(std::string const & channel)
00159 {
00160 struct dvb_frontend_parameters frontend;
00161
00162 std::string configLine = parser.getConfigLine(channel);
00163
00164 frontend = parser.getFrontendParam(configLine);
00165 switch (type) {
00166 case FE_QPSK:
00167 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate,
00168 frontend.u.qpsk.fec_inner);
00169 break;
00170 case FE_QAM:
00171 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
00172 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
00173 break;
00174 case FE_OFDM:
00175 tuneDVB_T(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
00176 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
00177 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
00178 frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
00179 break;
00180 default:
00181 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
00182 }
00183 }
00184
00185 prefix_ void senf::DVBSocketController::tuneDVB_T(unsigned int frequency,
00186 fe_spectral_inversion_t inversion,
00187 fe_bandwidth_t bandwidth,
00188 fe_code_rate_t code_rate_HP,
00189 fe_code_rate_t code_rate_LP,
00190 fe_modulation_t constellation,
00191 fe_transmit_mode_t transmission_mode,
00192 fe_guard_interval_t guard_interval,
00193 fe_hierarchy_t hierarchy_information
00194 )
00195 {
00196 if (type != FE_OFDM)
00197 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
00198 << getTypeString() << " for this operation you need a DVB-T Card!";
00199
00200 event.enable();
00201
00202 frontendHandle.protocol().setNonBlock();
00203 frontendHandle.protocol().tuneDVB_T(frequency,
00204 inversion,
00205 bandwidth,
00206 code_rate_HP,
00207 code_rate_LP,
00208 constellation,
00209 transmission_mode,
00210 guard_interval,
00211 hierarchy_information);
00212 }
00213
00214 prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency,
00215 fe_spectral_inversion_t inversion,
00216 unsigned int symbole_rate,
00217 fe_code_rate_t code_rate)
00218 {
00219 if (type != FE_QPSK)
00220 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
00221 << getTypeString() << " for this operation you need a DVB-S Card!";
00222
00223 event.enable();
00224
00225 frontendHandle.protocol().setNonBlock();
00226 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
00227 }
00228
00229 prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency,
00230 fe_spectral_inversion_t inversion,
00231 unsigned int symbol_rate,
00232 fe_code_rate_t fec_inner,
00233 fe_modulation_t modulation
00234 )
00235 {
00236 if (type != FE_QAM)
00237 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
00238 << getTypeString() << " for this operation you need a DVB-C Card!";
00239
00240 event.enable();
00241
00242 frontendHandle.protocol().setNonBlock();
00243
00244 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
00245 }
00246
00247 prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(std::string const & channel)
00248 {
00249 struct dvb_frontend_parameters frontend;
00250 dvb_frontend_event ev;
00251 std::string configLine = parser.getConfigLine(channel);
00252
00253 frontend = parser.getFrontendParam(configLine);
00254 switch (type) {
00255 case FE_QPSK:
00256 ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion,
00257 frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
00258 break;
00259 case FE_QAM:
00260 ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
00261 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
00262 break;
00263 case FE_OFDM:
00264 ev = tuneDVB_T_sync(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
00265 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
00266 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
00267 frontend.u.ofdm.guard_interval,
00268 frontend.u.ofdm.hierarchy_information);
00269 break;
00270 default:
00271 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
00272 }
00273 return ev;
00274 }
00275
00276 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(unsigned int frequency,
00277 fe_spectral_inversion_t inversion,
00278 fe_bandwidth_t bandwidth,
00279 fe_code_rate_t code_rate_HP,
00280 fe_code_rate_t code_rate_LP,
00281 fe_modulation_t constellation,
00282 fe_transmit_mode_t transmission_mode,
00283 fe_guard_interval_t guard_interval,
00284 fe_hierarchy_t hierarchy_information
00285 )
00286 {
00287 if (type != FE_OFDM)
00288 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
00289 << getTypeString() << " for this operation you need a DVB-T Card!";
00290
00291 event.disable();
00292
00293 frontendHandle.protocol().setNonBlock(false);
00294
00295 frontendHandle.protocol().tuneDVB_T(frequency,
00296 inversion,
00297 bandwidth,
00298 code_rate_HP,
00299 code_rate_LP,
00300 constellation,
00301 transmission_mode,
00302 guard_interval,
00303 hierarchy_information);
00304
00305 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
00306 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
00307
00308 return frontendHandle.protocol().getEvent();
00309 }
00310
00311 prefix_ dvb_frontend_event
00312 senf::DVBSocketController::tuneDVB_S_sync(unsigned int frequency,
00313 fe_spectral_inversion_t inversion,
00314 unsigned int symbole_rate, fe_code_rate_t code_rate)
00315 {
00316 if (type != FE_QPSK)
00317 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
00318 << getTypeString() << " for this operation you need a DVB-S Card!";
00319
00320 event.disable();
00321
00322 frontendHandle.protocol().setNonBlock(false);
00323
00324 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
00325
00326 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
00327 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
00328 return frontendHandle.protocol().getEvent();
00329 }
00330
00331 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency,
00332 fe_spectral_inversion_t inversion,
00333 unsigned int symbol_rate,
00334 fe_code_rate_t fec_inner,
00335 fe_modulation_t modulation
00336 )
00337 {
00338 if (type != FE_QAM)
00339 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
00340 << getTypeString() << " for this operation you need a DVB-C Card!";
00341
00342 event.disable();
00343
00344 frontendHandle.protocol().setNonBlock(false);
00345
00346 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
00347 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
00348 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
00349
00350 return frontendHandle.protocol().getEvent();
00351 }
00352
00353
00354 prefix_ std::string senf::DVBSocketController::getTypeString()
00355 {
00356 switch (type) {
00357 case FE_QPSK:
00358 return "DVB-S";
00359 case FE_QAM:
00360 return "DVB-C";
00361 case FE_OFDM:
00362 return "DVB-T";
00363 default:
00364 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
00365 }
00366 }
00367
00368 prefix_ unsigned int senf::DVBSocketController::bitErrorRate()
00369 {
00370 return frontendHandle.protocol().bitErrorRate();
00371 }
00372
00373 prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio()
00374 {
00375 return frontendHandle.protocol().signalNoiseRatio();
00376 }
00377
00378 prefix_ unsigned int senf::DVBSocketController::signalStrength()
00379 {
00380 return frontendHandle.protocol().signalStrength();
00381 }
00382
00383 prefix_ std::string senf::DVBSocketController::getTuneInfo(std::string const & conf)
00384 {
00385 const char* cConf = conf.c_str();
00386 std::stringstream info;
00387
00388 fe_status_t status;
00389 frontendHandle.protocol().setNonBlock(false);
00390 uint16_t snr, signal;
00391 uint32_t ber, uncorrected_blocks;
00392 status = frontendHandle.protocol().status();
00393 snr = frontendHandle.protocol().signalNoiseRatio();
00394 signal = frontendHandle.protocol().signalStrength();
00395 ber = frontendHandle.protocol().bitErrorRate();
00396 uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
00397
00398 info << std::hex;
00399
00400 for (unsigned int i = 0; i < conf.size(); ++i) {
00401 if (i>0)
00402 info << " | ";
00403 switch (cConf[i]) {
00404 case 'S' :
00405 info << "signal " << signal;
00406 break;
00407 case 's' :
00408 info << "snr " << snr;
00409 break;
00410 case 'b' :
00411 info << "ber " << ber;
00412 break;
00413 case 'u' :
00414 info << "unc " << uncorrected_blocks;
00415 break;
00416 case 'f' :
00417 info << "status: " << status2String(status);
00418 break;
00419 default:
00420 break;
00421 }
00422 }
00423 return info.str();
00424 }
00425
00426 prefix_ std::string senf::DVBSocketController::status2String(fe_status_t status)
00427 {
00428 std::string s("");
00429 if (status & FE_HAS_LOCK)
00430 return s += "HAS LOCK";
00431 if (status & FE_HAS_CARRIER)
00432 s += "HAS CARRIER ";
00433 if (status & FE_HAS_VITERBI)
00434 s += "HAS VITERBI ";
00435 if (status & FE_HAS_SYNC)
00436 s += "HAS SYNC ";
00437 if (status & FE_HAS_SIGNAL)
00438 s += "HAS SIGNAL ";
00439 if (status & FE_TIMEDOUT)
00440 s += "TIMED OUT ";
00441 if (status & FE_REINIT)
00442 s += "REINIT ";
00443
00444 return s;
00445 }
00446
00447 prefix_ fe_type_t senf::DVBSocketController::getType()
00448 {
00449 return type;
00450 }
00451
00452 prefix_ void senf::DVBSocketController::readEvent(int event)
00453 {
00454 if (cb)
00455 cb(frontendHandle.protocol().getEvent());
00456 }
00457
00458 prefix_ void senf::DVBSocketController::initConsole()
00459 {
00460 namespace fty = console::factory;
00461 namespace kw = console::kw;
00462
00463 dir.doc("DVB Controller " + controllerNr);
00464 ++controllerNr;
00465
00466 dir.add("type", fty::Command(&DVBSocketController::getTypeString, this)
00467 .doc("Shows actual type of card DVB-{T, S, C}") );
00468
00469 dir.add("info", fty::Command(&DVBSocketController::getTuneInfo, this)
00470 .doc("Returns a string which shows actual tuning status.\n"
00471 "'S' prints signal strength (in hex)\n"
00472 "'s' prints singal to noise ration (in hex)\n"
00473 "'b' prints bit error rate (in hex)\n"
00474 "'u' prints uncorrected blocks (in hex)\n"
00475 "'f' prints readable overal status e.g. 'Has Lock'\n\n"
00476 "These characters can be used to form the output. Be aware, some\n"
00477 "features may not be supported be your current driver implementation\n"
00478 "and could end in throwing an exception!")
00479 .arg("conf", "Ssbuf", kw::default_value = "Ssbuf") );
00480
00481 dir.add("tune", fty::Command(&DVBSocketController::tuneToCMD, this)
00482 .doc("tunes to channel listet in the configfile.")
00483 .arg("channel", "channel to tune")
00484 .arg("mode", "mode 'sync' or 'async'", kw::default_value = "async") );
00485 }
00486
00487
00488 #undef prefix_
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499