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_, const Callback & cb_)
44 frontendHandle( frontendHandle_ ),
45 type( frontendHandle.protocol().getInfo().type ),
50 event( "senf::DVBSocketController::readEvent", senf::membind(&DVBSocketController::readEvent, this), frontendHandle, senf::scheduler::FdEvent::EV_PRIO, false )
55 prefix_ senf::DVBSocketController::~DVBSocketController()
58 prefix_ senf::DVBDemuxSectionHandle
59 senf::DVBSocketController::createDVBDemuxSectionHandle(int adapternumber, int demuxnumber,
62 DVBDemuxSectionHandle sectionHandle(adapternumber, demuxnumber);
64 this->addToConsole(sectionHandle);
69 prefix_ senf::DVBDemuxPESHandle
70 senf::DVBSocketController::createDVBDemuxPESHandle(int adapternumber, int demuxnumber,
73 DVBDemuxPESHandle pesHandle(adapternumber, demuxnumber);
75 this->addToConsole(pesHandle);
80 prefix_ void senf::DVBSocketController::addToConsole(senf::DVBDemuxSectionHandle sh)
82 boost::shared_ptr<DVBSectionProtocolWrapper> wrap(new DVBSectionProtocolWrapper(sh));
83 sh.protocol().addWrapper(wrap);
84 dir.node().add("section" + senf::str(sectionNr), wrap->dir);
88 prefix_ void senf::DVBSocketController::addToConsole(senf::DVBDemuxPESHandle sh)
90 boost::shared_ptr<DVBPESProtocolWrapper> wrap(new DVBPESProtocolWrapper(sh));
91 sh.protocol().addWrapper(wrap);
92 dir.node().add("pes"+ senf::str(pesNr), wrap->dir);
96 prefix_ void senf::DVBSocketController::tuneToCMD(const string & input, const string & mode)
98 struct dvb_frontend_parameters frontend;
100 // no valid configline, so it will be treaten like a channel name
101 if (input.find(":")==string::npos)
103 if (mode.c_str()[0]=='a')
109 // add psydo name "foo" to complete configline syntax
110 frontend = parser.getFrontendParam("foo:"+input);
112 if (mode.c_str()[0]=='a') {
115 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
118 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
121 tuneDVB_T(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth, frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP, frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode, frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
124 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
130 tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
133 tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
136 tuneDVB_T_sync(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth, frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP, frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode, frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
139 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
144 prefix_ void senf::DVBSocketController::tuneTo(const string & channel)
146 struct dvb_frontend_parameters frontend;
148 string configLine = parser.getConfigLine(channel);
150 frontend = parser.getFrontendParam(configLine);
153 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
156 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
159 tuneDVB_T(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth, frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP, frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode, frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
162 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
166 prefix_ void senf::DVBSocketController::tuneDVB_T(unsigned int frequency,
167 fe_spectral_inversion_t inversion,
168 fe_bandwidth_t bandwidth,
169 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
170 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
171 fe_modulation_t constellation, /* modulation type (see above) */
172 fe_transmit_mode_t transmission_mode,
173 fe_guard_interval_t guard_interval,
174 fe_hierarchy_t hierarchy_information
178 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
182 frontendHandle.protocol().setNonBlock();
183 frontendHandle.protocol().tuneDVB_T(frequency,
191 hierarchy_information);
194 prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate)
197 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
201 frontendHandle.protocol().setNonBlock();
202 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
205 prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency,
206 fe_spectral_inversion_t inversion,
207 unsigned int symbol_rate,
208 fe_code_rate_t fec_inner,
209 fe_modulation_t modulation
213 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
217 frontendHandle.protocol().setNonBlock();
219 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
222 prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(const string & channel)
224 struct dvb_frontend_parameters frontend;
225 dvb_frontend_event ev;
226 string configLine = parser.getConfigLine(channel);
228 frontend = parser.getFrontendParam(configLine);
231 ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
234 ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
237 ev = tuneDVB_T_sync(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth, frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP, frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode, frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
240 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
245 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(unsigned int frequency,
246 fe_spectral_inversion_t inversion,
247 fe_bandwidth_t bandwidth,
248 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
249 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
250 fe_modulation_t constellation, /* modulation type (see above) */
251 fe_transmit_mode_t transmission_mode,
252 fe_guard_interval_t guard_interval,
253 fe_hierarchy_t hierarchy_information
257 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
261 frontendHandle.protocol().setNonBlock(false);
263 frontendHandle.protocol().tuneDVB_T(frequency,
271 hierarchy_information);
273 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
274 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
276 return frontendHandle.protocol().getEvent();
279 prefix_ dvb_frontend_event
280 senf::DVBSocketController::tuneDVB_S_sync(unsigned int frequency,
281 fe_spectral_inversion_t inversion,
282 unsigned int symbole_rate, fe_code_rate_t code_rate)
285 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
289 frontendHandle.protocol().setNonBlock(false);
291 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
293 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
294 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
295 return frontendHandle.protocol().getEvent();
298 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency,
299 fe_spectral_inversion_t inversion,
300 unsigned int symbol_rate,
301 fe_code_rate_t fec_inner,
302 fe_modulation_t modulation
306 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
310 frontendHandle.protocol().setNonBlock(false);
312 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
313 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
314 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
316 return frontendHandle.protocol().getEvent();
320 prefix_ string senf::DVBSocketController::getTypeString()
330 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
334 prefix_ unsigned int senf::DVBSocketController::bitErrorRate()
336 return frontendHandle.protocol().bitErrorRate();
339 prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio()
341 return frontendHandle.protocol().signalNoiseRatio();
344 prefix_ unsigned int senf::DVBSocketController::signalStrength()
346 return frontendHandle.protocol().signalStrength();
349 prefix_ string senf::DVBSocketController::getTuneInfo(const string & conf)
351 const char* cConf = conf.c_str();
355 frontendHandle.protocol().setNonBlock(false);
356 uint16_t snr, signal;
357 uint32_t ber, uncorrected_blocks;
358 status = frontendHandle.protocol().status();
359 snr = frontendHandle.protocol().signalNoiseRatio();
360 signal = frontendHandle.protocol().signalStrength();
361 ber = frontendHandle.protocol().bitErrorRate();
362 uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
366 for (unsigned int i = 0; i < conf.size(); ++i) {
371 info << "signal " << signal;
374 info << "snr " << snr;
377 info << "ber " << ber;
380 info << "unc " << uncorrected_blocks;
383 info << "status: " << status2String(status);
392 prefix_ string senf::DVBSocketController::status2String(fe_status_t status)
395 if (status & FE_HAS_LOCK)
396 return s += "HAS LOCK";
397 if (status & FE_HAS_CARRIER)
399 if (status & FE_HAS_VITERBI)
401 if (status & FE_HAS_SYNC)
403 if (status & FE_HAS_SIGNAL)
405 if (status & FE_TIMEDOUT)
407 if (status & FE_REINIT)
415 prefix_ fe_type_t senf::DVBSocketController::getType()
420 prefix_ void senf::DVBSocketController::readEvent(int event)
423 cb(frontendHandle.protocol().getEvent());
426 prefix_ void senf::DVBSocketController::initConsole()
428 namespace fty = senf::console::factory;
429 namespace kw = senf::console::kw;
431 dir.doc("DVB Controller " + controllerNr);
434 dir.add("type", fty::Command(&DVBSocketController::getTypeString, this)
435 .doc("Shows actual type of card DVB-{T, S, C}") );
437 dir.add("info", fty::Command(&DVBSocketController::getTuneInfo, this)
438 .doc("Returns a string which shows actual tuning status.\n"
439 "'S' prints signal strength (in hex)\n"
440 "'s' prints singal to noise ration (in hex)\n"
441 "'b' prints bit error rate (in hex)\n"
442 "'u' prints uncorrected blocks (in hex)\n"
443 "'f' prints readable overal status e.g. 'Has Lock'\n\n"
444 "These characters can be used to form the output. Be aware, some\n"
445 "features may not be supported be your current driver implementation\n"
446 "and could end in throwing an exception!")
447 .arg("conf", "Ssbuf", kw::default_value = "Ssbuf") );
449 dir.add("tune", fty::Command(&DVBSocketController::tuneToCMD, this)
450 .doc("tunes to channel listet in the configfile.")
451 .arg("channel", "channel to tune")
452 .arg("mode", "mode 'sync' or 'async'", kw::default_value = "async") );
455 ///////////////////////////////cc.e////////////////////////////////////////