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()
59 prefix_ senf::DVBDemuxSectionHandle senf::DVBSocketController::createDVBDemuxSectionHandle( int adapternumber, int demuxnumber, bool addToConsole ){
60 DVBDemuxSectionHandle sectionHandle(adapternumber, demuxnumber);
62 this->addToConsole(sectionHandle);
67 prefix_ senf::DVBDemuxPESHandle senf::DVBSocketController::createDVBDemuxPESHandle( int adapternumber, int demuxnumber, bool addToConsole ){
68 DVBDemuxPESHandle pesHandle(adapternumber, demuxnumber);
70 this->addToConsole(pesHandle);
75 prefix_ void senf::DVBSocketController::addToConsole(senf::DVBDemuxSectionHandle sh){
76 boost::shared_ptr<DVBSectionProtocolWrapper> wrap(new DVBSectionProtocolWrapper(sh));
77 sh.protocol().addWrapper(wrap);
78 dir.node().add("section" + senf::str(sectionNr), wrap->dir);
81 prefix_ void senf::DVBSocketController::addToConsole(senf::DVBDemuxPESHandle sh){
82 boost::shared_ptr<DVBPESProtocolWrapper> wrap(new DVBPESProtocolWrapper(sh));
83 sh.protocol().addWrapper(wrap);
84 dir.node().add("pes"+ senf::str(pesNr), wrap->dir);
88 prefix_ void senf::DVBSocketController::tuneToCMD(const string & input, const string & mode)
90 struct dvb_frontend_parameters frontend;
92 // no valid configline, so it will be treaten like a channel name
93 if (input.find(":")==string::npos){
94 if (mode.c_str()[0]=='a')
100 // add psydo name "foo" to complete configline syntax
101 frontend = parser.getFrontendParam("foo:"+input);
103 if (mode.c_str()[0]=='a'){
106 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
109 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
112 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);
115 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
121 tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
124 tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
127 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);
130 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
135 prefix_ void senf::DVBSocketController::tuneTo(const string & channel)
137 struct dvb_frontend_parameters frontend;
139 string configLine = parser.getConfigLine(channel);
141 frontend = parser.getFrontendParam(configLine);
144 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
147 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
150 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);
153 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
157 prefix_ void senf::DVBSocketController::tuneDVB_T(unsigned int frequency,
158 fe_spectral_inversion_t inversion,
159 fe_bandwidth_t bandwidth,
160 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
161 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
162 fe_modulation_t constellation, /* modulation type (see above) */
163 fe_transmit_mode_t transmission_mode,
164 fe_guard_interval_t guard_interval,
165 fe_hierarchy_t hierarchy_information
169 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
173 frontendHandle.protocol().setNonBlock();
174 frontendHandle.protocol().tuneDVB_T(frequency,
182 hierarchy_information);
185 prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate)
188 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
192 frontendHandle.protocol().setNonBlock();
193 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
196 prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency,
197 fe_spectral_inversion_t inversion,
198 unsigned int symbol_rate,
199 fe_code_rate_t fec_inner,
200 fe_modulation_t modulation
204 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
208 frontendHandle.protocol().setNonBlock();
210 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
213 prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(const string & channel)
215 struct dvb_frontend_parameters frontend;
216 dvb_frontend_event ev;
217 string configLine = parser.getConfigLine(channel);
219 frontend = parser.getFrontendParam(configLine);
222 ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
225 ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
228 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);
231 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
236 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(unsigned int frequency,
237 fe_spectral_inversion_t inversion,
238 fe_bandwidth_t bandwidth,
239 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
240 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
241 fe_modulation_t constellation, /* modulation type (see above) */
242 fe_transmit_mode_t transmission_mode,
243 fe_guard_interval_t guard_interval,
244 fe_hierarchy_t hierarchy_information
248 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
252 frontendHandle.protocol().setNonBlock(false);
254 frontendHandle.protocol().tuneDVB_T(frequency,
262 hierarchy_information);
264 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
265 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
267 return frontendHandle.protocol().getEvent();
270 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_S_sync(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate){
272 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
276 frontendHandle.protocol().setNonBlock(false);
278 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
280 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
281 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
282 return frontendHandle.protocol().getEvent();
285 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency,
286 fe_spectral_inversion_t inversion,
287 unsigned int symbol_rate,
288 fe_code_rate_t fec_inner,
289 fe_modulation_t modulation
293 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
297 frontendHandle.protocol().setNonBlock(false);
299 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
300 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
301 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
303 return frontendHandle.protocol().getEvent();
307 prefix_ string senf::DVBSocketController::getTypeString()
317 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
321 prefix_ unsigned int senf::DVBSocketController::bitErrorRate()
323 return frontendHandle.protocol().bitErrorRate();
326 prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio()
328 return frontendHandle.protocol().signalNoiseRatio();
331 prefix_ unsigned int senf::DVBSocketController::signalStrength()
333 return frontendHandle.protocol().signalStrength();
336 prefix_ string senf::DVBSocketController::getTuneInfo(const string & conf)
338 const char* cConf = conf.c_str();
342 frontendHandle.protocol().setNonBlock(false);
343 uint16_t snr, signal;
344 uint32_t ber, uncorrected_blocks;
345 status = frontendHandle.protocol().status();
346 snr = frontendHandle.protocol().signalNoiseRatio();
347 signal = frontendHandle.protocol().signalStrength();
348 ber = frontendHandle.protocol().bitErrorRate();
349 uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
353 for(unsigned int i = 0; i < conf.size(); ++i){
358 info << "signal " << signal;
361 info << "snr " << snr;
364 info << "ber " << ber;
367 info << "unc " << uncorrected_blocks;
370 info << "status: " << status2String(status);
379 prefix_ string senf::DVBSocketController::status2String(fe_status_t status)
382 if (status & FE_HAS_LOCK)
383 return s += "HAS LOCK";
384 if (status & FE_HAS_CARRIER)
386 if (status & FE_HAS_VITERBI)
388 if (status & FE_HAS_SYNC)
390 if (status & FE_HAS_SIGNAL)
392 if (status & FE_TIMEDOUT)
394 if (status & FE_REINIT)
402 prefix_ fe_type_t senf::DVBSocketController::getType()
407 prefix_ void senf::DVBSocketController::readEvent(int event)
410 cb(frontendHandle.protocol().getEvent());
413 prefix_ void senf::DVBSocketController::initConsole()
415 // binding functions to console
416 namespace kw = senf::console::kw;
417 dir.doc("DVB Controller " + controllerNr);
420 dir.add("type", &DVBSocketController::getTypeString)
421 .doc("Shows actual type of card DVB-{T, S, C}");
423 dir.add("info", &DVBSocketController::getTuneInfo)
424 .doc("Returns a string which shows actual tuning status.\n\
425 \"S\" prints signal strength (in hex)\n\
426 \"s\" prints singal to noise ration (in hex)\n\
427 \"b\" prints bit error rate (in hex)\n\
428 \"u\" prints uncorrected blocks (in hex)\n\
429 \"f\" prints readable overal status e.g. \"Has Lock\"\n\n\
430 These characters can be used to form the output. Be aware, some\n\
431 features may not be supported be your current driver implementation\n\
432 and could end in throwing an exception!")
433 .arg("conf", "Ssbuf", kw::default_value = "Ssbuf");
435 dir.add("tune", &DVBSocketController::tuneToCMD)
436 .doc("tunes to channel listet in the configfile.")
437 .arg("channel", "channel to tune")
438 .arg("mode", "mode \"sync\" or \"async\"", kw::default_value = "async");
441 ///////////////////////////////cc.e////////////////////////////////////////