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 DVBSocketController 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"
35 ///////////////////////////////cc.p////////////////////////////////////////
39 senf::DVBSocketController::DVBSocketController(DVBFrontendHandle frontendHandle_, DVBDemuxSectionHandle sectionHandle_ , const Callback & cb_)
41 frontendHandle( frontendHandle_ ),
42 sectionHandle( sectionHandle_ ),
43 type( frontendHandle.protocol().getInfo().type ),
46 event( "senf::DVBSocketController::readEvent", senf::membind(&DVBSocketController::readEvent, this), frontendHandle, senf::scheduler::FdEvent::EV_PRIO, false )
51 prefix_ senf::DVBSocketController::~DVBSocketController()
55 prefix_ void senf::DVBSocketController::tuneToCMD(const string & input, const string & mode)
57 struct dvb_frontend_parameters frontend;
59 // no valid configline, so it will be treaten like a channel name
60 if (input.find(":")==string::npos){
61 if (mode.c_str()[0]=='a')
67 // add psydo name "foo" to complete configline syntax
68 frontend = parser.getFrontendParam("foo:"+input);
70 if (mode.c_str()[0]=='a'){
73 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
76 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
79 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);
82 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
88 tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
91 tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
94 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);
97 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
102 prefix_ void senf::DVBSocketController::tuneTo(const string & channel)
104 struct dvb_frontend_parameters frontend;
106 string configLine = parser.getConfigLine(channel);
108 frontend = parser.getFrontendParam(configLine);
111 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
114 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
117 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);
120 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
124 prefix_ void senf::DVBSocketController::tuneDVB_T(unsigned int frequency,
125 fe_spectral_inversion_t inversion,
126 fe_bandwidth_t bandwidth,
127 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
128 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
129 fe_modulation_t constellation, /* modulation type (see above) */
130 fe_transmit_mode_t transmission_mode,
131 fe_guard_interval_t guard_interval,
132 fe_hierarchy_t hierarchy_information
136 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
140 frontendHandle.protocol().setNonBlock();
141 frontendHandle.protocol().tuneDVB_T(frequency,
149 hierarchy_information);
152 prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate)
155 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
159 frontendHandle.protocol().setNonBlock();
160 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
163 prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency,
164 fe_spectral_inversion_t inversion,
165 unsigned int symbol_rate,
166 fe_code_rate_t fec_inner,
167 fe_modulation_t modulation
171 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
175 frontendHandle.protocol().setNonBlock();
177 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
180 prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(const string & channel)
182 struct dvb_frontend_parameters frontend;
183 dvb_frontend_event ev;
184 string configLine = parser.getConfigLine(channel);
186 frontend = parser.getFrontendParam(configLine);
189 ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
192 ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
195 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);
198 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
203 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(unsigned int frequency,
204 fe_spectral_inversion_t inversion,
205 fe_bandwidth_t bandwidth,
206 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
207 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
208 fe_modulation_t constellation, /* modulation type (see above) */
209 fe_transmit_mode_t transmission_mode,
210 fe_guard_interval_t guard_interval,
211 fe_hierarchy_t hierarchy_information
215 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
219 frontendHandle.protocol().setNonBlock(false);
221 frontendHandle.protocol().tuneDVB_T(frequency,
229 hierarchy_information);
231 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
232 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
234 return frontendHandle.protocol().getEvent();
237 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){
239 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
243 frontendHandle.protocol().setNonBlock(false);
245 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
247 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
248 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
249 return frontendHandle.protocol().getEvent();
252 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency,
253 fe_spectral_inversion_t inversion,
254 unsigned int symbol_rate,
255 fe_code_rate_t fec_inner,
256 fe_modulation_t modulation
260 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
264 frontendHandle.protocol().setNonBlock(false);
266 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
267 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
268 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
270 return frontendHandle.protocol().getEvent();
274 prefix_ string senf::DVBSocketController::getTypeString()
284 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
288 prefix_ unsigned int senf::DVBSocketController::bitErrorRate()
290 return frontendHandle.protocol().bitErrorRate();
293 prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio()
295 return frontendHandle.protocol().signalNoiseRatio();
298 prefix_ unsigned int senf::DVBSocketController::signalStrength()
300 return frontendHandle.protocol().signalStrength();
303 prefix_ string senf::DVBSocketController::getTuneInfo(const string & conf)
305 const char* cConf = conf.c_str();
309 frontendHandle.protocol().setNonBlock(false);
310 uint16_t snr, signal;
311 uint32_t ber, uncorrected_blocks;
312 status = frontendHandle.protocol().status();
313 snr = frontendHandle.protocol().signalNoiseRatio();
314 signal = frontendHandle.protocol().signalStrength();
315 ber = frontendHandle.protocol().bitErrorRate();
316 uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
320 for(unsigned int i = 0; i < conf.size(); ++i){
325 info << "signal " << signal;
328 info << "snr " << snr;
331 info << "ber " << ber;
334 info << "unc " << uncorrected_blocks;
337 info << "status: " << status2String(status);
346 prefix_ string senf::DVBSocketController::status2String(fe_status_t status)
349 if (status & FE_HAS_LOCK)
350 return s += "HAS LOCK";
351 if (status & FE_HAS_CARRIER)
353 if (status & FE_HAS_VITERBI)
355 if (status & FE_HAS_SYNC)
357 if (status & FE_HAS_SIGNAL)
359 if (status & FE_TIMEDOUT)
361 if (status & FE_REINIT)
367 prefix_ void senf::DVBSocketController::setSectionFilter(unsigned short int pid,
372 unsigned int timeout)
374 sectionHandle.protocol().setSectionFilter(pid, timeout, flags, filter, mask, mode);
378 prefix_ void senf::DVBSocketController::setBufferSize(unsigned long size)
380 sectionHandle.protocol().setBufferSize(size);
383 prefix_ void senf::DVBSocketController::startFiltering()
385 sectionHandle.protocol().startFiltering();
388 prefix_ void senf::DVBSocketController::stopFiltering()
390 sectionHandle.protocol().stopFiltering();
393 prefix_ fe_type_t senf::DVBSocketController::getType()
398 prefix_ void senf::DVBSocketController::readEvent(int event)
401 cb(frontendHandle.protocol().getEvent());
404 prefix_ void senf::DVBSocketController::initConsole()
406 // binding functions to console
407 namespace kw = senf::console::kw;
408 dir.doc("DVB Controller");
410 dir.add("type", &DVBSocketController::getTypeString)
411 .doc("Shows actual type of card DVB-{T, S, C}");
413 dir.add("info", &DVBSocketController::getTuneInfo)
414 .doc("Returns a string which shows actual tuning status.\n\
415 \"S\" prints signal strength (in hex)\n\
416 \"s\" prints singal to noise ration (in hex)\n\
417 \"b\" prints bit error rate (in hex)\n\
418 \"u\" prints uncorrected blocks (in hex)\n\
419 \"f\" prints readable overal status e.g. \"Has Lock\"\n\n\
420 These characters can be used to form the output. Be aware, some\n\
421 features may not be supported be your current driver implementation\n\
422 and could end in throwing an exception!")
423 .arg("conf", "Ssbuf", kw::default_value = "Ssbuf");
425 dir.add("tune", &DVBSocketController::tuneToCMD)
426 .doc("tunes to channel listet in the configfile.")
427 .arg("channel", "channel to tune")
428 .arg("mode", "mode \"sync\" or \"async\"", kw::default_value = "async");
430 dir.add("buffersize", &DVBSocketController::setBufferSize)
431 .doc("Set the size of the circular buffer used for filtered data.")
432 .arg("size", "in byte");
434 dir.add("start", &DVBSocketController::startFiltering)
435 .doc("Starts filtering");
437 dir.add("stop", &DVBSocketController::setBufferSize)
438 .doc("Stops filtering");
440 dir.add("filter", &DVBSocketController::setSectionFilter)
441 .arg("pid", "pid to filter")
442 .arg("filter", "filter", kw::default_value = 62, kw::default_doc = "0x3e")
443 .arg("flags", "or-able: DMX_CHECK_CRC(0x01), DMX_ONESHOT(0x02), DMX_IMMEDIATE_START(0x04), DMX_KERNEL_CLIENT(0x8000)", kw::default_value = DMX_IMMEDIATE_START | DMX_CHECK_CRC, kw::default_doc = "0x05")
444 .arg("mask", "mask", kw::default_value = 0xff, kw::default_doc = "0xff")
445 .arg("mode", "mode", kw::default_value = 0, kw::default_doc = "0x00")
446 .arg("timeout", "timeout", kw::default_value = 0, kw::default_doc = "0x00")
447 .doc("Sets parameters for section filter.");
449 dir.add("stop", &DVBSocketController::setBufferSize)
450 .doc("Stops filtering");
453 ///////////////////////////////cc.e////////////////////////////////////////