4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 // Anton Gillert <atx@berlios.de>
8 // This program is free software; you can redistribute it and/or modify
9 // it under the terms of the GNU General Public License as published by
10 // the Free Software Foundation; either version 2 of the License, or
11 // (at your option) any later version.
13 // This program is distributed in the hope that it will be useful,
14 // but WITHOUT ANY WARRANTY; without even the implied warranty of
15 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 // GNU General Public License for more details.
18 // You should have received a copy of the GNU General Public License
19 // along with this program; if not, write to the
20 // Free Software Foundation, Inc.,
21 // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
24 \brief DVBSocketControlle-r non-inline non-template implementation */
26 #include "DVBSocketController.hh"
30 #include <senf/Utils/Exception.hh>
31 #include <senf/Utils/Logger/Logger.hh>
32 #include <senf/Utils/membind.hh>
33 #include <boost/shared_ptr.hpp>
36 ///////////////////////////////cc.p////////////////////////////////////////
40 unsigned int senf::DVBSocketController::controllerNr(0);
42 senf::DVBSocketController::DVBSocketController(DVBFrontendHandle frontendHandle_,
45 frontendHandle( frontendHandle_ ),
46 type( frontendHandle.protocol().getInfo().type ),
51 event( "senf::DVBSocketController::readEvent",
52 senf::membind(&DVBSocketController::readEvent, this), frontendHandle,
53 senf::scheduler::FdEvent::EV_PRIO, false )
58 prefix_ senf::DVBSocketController::~DVBSocketController()
61 prefix_ senf::DVBDemuxSectionHandle
62 senf::DVBSocketController::createDVBDemuxSectionHandle(int adapternumber, int demuxnumber,
65 DVBDemuxSectionHandle sectionHandle(adapternumber, demuxnumber);
67 this->addToConsole(sectionHandle);
72 prefix_ senf::DVBDemuxPESHandle
73 senf::DVBSocketController::createDVBDemuxPESHandle(int adapternumber, int demuxnumber,
76 DVBDemuxPESHandle pesHandle(adapternumber, demuxnumber);
78 this->addToConsole(pesHandle);
83 prefix_ void senf::DVBSocketController::addToConsole(senf::DVBDemuxSectionHandle sh)
85 boost::shared_ptr<DVBSectionProtocolWrapper> wrap(new DVBSectionProtocolWrapper(sh));
86 sh.protocol().addWrapper(wrap);
87 dir.node().add("section" + senf::str(sectionNr), wrap->dir);
91 prefix_ void senf::DVBSocketController::addToConsole(senf::DVBDemuxPESHandle sh)
93 boost::shared_ptr<DVBPESProtocolWrapper> wrap(new DVBPESProtocolWrapper(sh));
94 sh.protocol().addWrapper(wrap);
95 dir.node().add("pes"+ senf::str(pesNr), wrap->dir);
99 prefix_ void senf::DVBSocketController::tuneToCMD(const string & input, const string & mode)
101 struct dvb_frontend_parameters frontend;
103 // no valid configline, so it will be treaten like a channel name
104 if (input.find(":")==string::npos)
106 if (mode.c_str()[0]=='a')
112 // add psydo name "foo" to complete configline syntax
113 frontend = parser.getFrontendParam("foo:"+input);
115 if (mode.c_str()[0]=='a') {
118 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate,
119 frontend.u.qpsk.fec_inner);
122 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
123 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
126 tuneDVB_T(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
127 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
128 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
129 frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
132 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
138 tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate,
139 frontend.u.qpsk.fec_inner);
142 tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
143 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
146 tuneDVB_T_sync(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
147 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
148 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
149 frontend.u.ofdm.guard_interval,
150 frontend.u.ofdm.hierarchy_information);
153 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
158 prefix_ void senf::DVBSocketController::tuneTo(const string & channel)
160 struct dvb_frontend_parameters frontend;
162 string configLine = parser.getConfigLine(channel);
164 frontend = parser.getFrontendParam(configLine);
167 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate,
168 frontend.u.qpsk.fec_inner);
171 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
172 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
175 tuneDVB_T(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
176 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
177 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
178 frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
181 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
185 prefix_ void senf::DVBSocketController::tuneDVB_T(unsigned int frequency,
186 fe_spectral_inversion_t inversion,
187 fe_bandwidth_t bandwidth,
188 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
189 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
190 fe_modulation_t constellation, /* modulation type (see above) */
191 fe_transmit_mode_t transmission_mode,
192 fe_guard_interval_t guard_interval,
193 fe_hierarchy_t hierarchy_information
197 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
198 << getTypeString() << " for this operation you need a DVB-T Card!";
202 frontendHandle.protocol().setNonBlock();
203 frontendHandle.protocol().tuneDVB_T(frequency,
211 hierarchy_information);
214 prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency,
215 fe_spectral_inversion_t inversion,
216 unsigned int symbole_rate,
217 fe_code_rate_t code_rate)
220 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
221 << getTypeString() << " for this operation you need a DVB-S Card!";
225 frontendHandle.protocol().setNonBlock();
226 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
229 prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency,
230 fe_spectral_inversion_t inversion,
231 unsigned int symbol_rate,
232 fe_code_rate_t fec_inner,
233 fe_modulation_t modulation
237 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
238 << getTypeString() << " for this operation you need a DVB-C Card!";
242 frontendHandle.protocol().setNonBlock();
244 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
247 prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(const string & channel)
249 struct dvb_frontend_parameters frontend;
250 dvb_frontend_event ev;
251 string configLine = parser.getConfigLine(channel);
253 frontend = parser.getFrontendParam(configLine);
256 ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion,
257 frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
260 ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
261 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
264 ev = tuneDVB_T_sync(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
265 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
266 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
267 frontend.u.ofdm.guard_interval,
268 frontend.u.ofdm.hierarchy_information);
271 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
276 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(unsigned int frequency,
277 fe_spectral_inversion_t inversion,
278 fe_bandwidth_t bandwidth,
279 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
280 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
281 fe_modulation_t constellation, /* modulation type (see above) */
282 fe_transmit_mode_t transmission_mode,
283 fe_guard_interval_t guard_interval,
284 fe_hierarchy_t hierarchy_information
288 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
289 << getTypeString() << " for this operation you need a DVB-T Card!";
293 frontendHandle.protocol().setNonBlock(false);
295 frontendHandle.protocol().tuneDVB_T(frequency,
303 hierarchy_information);
305 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
306 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
308 return frontendHandle.protocol().getEvent();
311 prefix_ dvb_frontend_event
312 senf::DVBSocketController::tuneDVB_S_sync(unsigned int frequency,
313 fe_spectral_inversion_t inversion,
314 unsigned int symbole_rate, fe_code_rate_t code_rate)
317 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
318 << getTypeString() << " for this operation you need a DVB-S Card!";
322 frontendHandle.protocol().setNonBlock(false);
324 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
326 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
327 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
328 return frontendHandle.protocol().getEvent();
331 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency,
332 fe_spectral_inversion_t inversion,
333 unsigned int symbol_rate,
334 fe_code_rate_t fec_inner,
335 fe_modulation_t modulation
339 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
340 << getTypeString() << " for this operation you need a DVB-C Card!";
344 frontendHandle.protocol().setNonBlock(false);
346 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
347 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
348 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
350 return frontendHandle.protocol().getEvent();
354 prefix_ string senf::DVBSocketController::getTypeString()
364 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
368 prefix_ unsigned int senf::DVBSocketController::bitErrorRate()
370 return frontendHandle.protocol().bitErrorRate();
373 prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio()
375 return frontendHandle.protocol().signalNoiseRatio();
378 prefix_ unsigned int senf::DVBSocketController::signalStrength()
380 return frontendHandle.protocol().signalStrength();
383 prefix_ string senf::DVBSocketController::getTuneInfo(const string & conf)
385 const char* cConf = conf.c_str();
389 frontendHandle.protocol().setNonBlock(false);
390 uint16_t snr, signal;
391 uint32_t ber, uncorrected_blocks;
392 status = frontendHandle.protocol().status();
393 snr = frontendHandle.protocol().signalNoiseRatio();
394 signal = frontendHandle.protocol().signalStrength();
395 ber = frontendHandle.protocol().bitErrorRate();
396 uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
400 for (unsigned int i = 0; i < conf.size(); ++i) {
405 info << "signal " << signal;
408 info << "snr " << snr;
411 info << "ber " << ber;
414 info << "unc " << uncorrected_blocks;
417 info << "status: " << status2String(status);
426 prefix_ string senf::DVBSocketController::status2String(fe_status_t status)
429 if (status & FE_HAS_LOCK)
430 return s += "HAS LOCK";
431 if (status & FE_HAS_CARRIER)
433 if (status & FE_HAS_VITERBI)
435 if (status & FE_HAS_SYNC)
437 if (status & FE_HAS_SIGNAL)
439 if (status & FE_TIMEDOUT)
441 if (status & FE_REINIT)
449 prefix_ fe_type_t senf::DVBSocketController::getType()
454 prefix_ void senf::DVBSocketController::readEvent(int event)
457 cb(frontendHandle.protocol().getEvent());
460 prefix_ void senf::DVBSocketController::initConsole()
462 namespace fty = senf::console::factory;
463 namespace kw = senf::console::kw;
465 dir.doc("DVB Controller " + controllerNr);
468 dir.add("type", fty::Command(&DVBSocketController::getTypeString, this)
469 .doc("Shows actual type of card DVB-{T, S, C}") );
471 dir.add("info", fty::Command(&DVBSocketController::getTuneInfo, this)
472 .doc("Returns a string which shows actual tuning status.\n"
473 "'S' prints signal strength (in hex)\n"
474 "'s' prints singal to noise ration (in hex)\n"
475 "'b' prints bit error rate (in hex)\n"
476 "'u' prints uncorrected blocks (in hex)\n"
477 "'f' prints readable overal status e.g. 'Has Lock'\n\n"
478 "These characters can be used to form the output. Be aware, some\n"
479 "features may not be supported be your current driver implementation\n"
480 "and could end in throwing an exception!")
481 .arg("conf", "Ssbuf", kw::default_value = "Ssbuf") );
483 dir.add("tune", fty::Command(&DVBSocketController::tuneToCMD, this)
484 .doc("tunes to channel listet in the configfile.")
485 .arg("channel", "channel to tune")
486 .arg("mode", "mode 'sync' or 'async'", kw::default_value = "async") );
489 ///////////////////////////////cc.e////////////////////////////////////////
496 // c-file-style: "senf"
497 // indent-tabs-mode: nil
498 // ispell-local-dictionary: "american"
499 // compile-command: "scons -u test"
500 // comment-column: 40