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 #include "senf/Utils/Exception.hh"
25 #include "senf/Utils/Logger/Logger.hh"
26 #include "senf/Utils/membind.hh"
28 #include "DVBSocketController.hh"
35 senf::DVBSocketController::DVBSocketController(DVBFrontendHandle frontendHandle_, DVBDemuxSectionHandle sectionHandle_ , const Callback & cb_) :
37 frontendHandle( frontendHandle_ ),
38 sectionHandle( sectionHandle_ ),
39 type( frontendHandle.protocol().getInfo().type ),
42 event( "senf::DVBSocketController::readEvent", senf::membind(&DVBSocketController::readEvent, this), frontendHandle, senf::scheduler::FdEvent::EV_PRIO, false )
47 prefix_ senf::DVBSocketController::~DVBSocketController()
50 prefix_ void senf::DVBSocketController::tuneToCMD(const string & input, const string & mode){
51 struct dvb_frontend_parameters frontend;
54 // no valid configline, so it will be treaten like a channel name
55 if (input.find(":")==string::npos){
56 if (mode.c_str()[0]=='a')
62 // add psydo name "foo" to complete configline syntax
63 frontend = parser.getFrontendParam("foo:"+input);
65 if (mode.c_str()[0]=='a'){
68 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
71 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
74 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);
77 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
83 tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
86 tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
89 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);
92 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
97 prefix_ void senf::DVBSocketController::tuneTo(const string & channel)
99 struct dvb_frontend_parameters frontend;
101 string configLine = parser.getConfigLine(channel);
103 frontend = parser.getFrontendParam(configLine);
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.");
119 prefix_ void senf::DVBSocketController::tuneDVB_T(unsigned int frequency,
120 fe_spectral_inversion_t inversion,
121 fe_bandwidth_t bandwidth,
122 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
123 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
124 fe_modulation_t constellation, /* modulation type (see above) */
125 fe_transmit_mode_t transmission_mode,
126 fe_guard_interval_t guard_interval,
127 fe_hierarchy_t hierarchy_information
131 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
135 frontendHandle.protocol().setNonBlock();
136 frontendHandle.protocol().tuneDVB_T(frequency,
144 hierarchy_information);
147 prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate){
149 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
153 frontendHandle.protocol().setNonBlock();
154 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
157 prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency,
158 fe_spectral_inversion_t inversion,
159 unsigned int symbol_rate,
160 fe_code_rate_t fec_inner,
161 fe_modulation_t modulation
165 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
169 frontendHandle.protocol().setNonBlock();
171 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
174 prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(const string & channel)
176 struct dvb_frontend_parameters frontend;
177 dvb_frontend_event ev;
178 string configLine = parser.getConfigLine(channel);
180 frontend = parser.getFrontendParam(configLine);
183 ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
186 ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
189 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);
192 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
197 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(unsigned int frequency,
198 fe_spectral_inversion_t inversion,
199 fe_bandwidth_t bandwidth,
200 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
201 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
202 fe_modulation_t constellation, /* modulation type (see above) */
203 fe_transmit_mode_t transmission_mode,
204 fe_guard_interval_t guard_interval,
205 fe_hierarchy_t hierarchy_information
209 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
213 frontendHandle.protocol().setNonBlock(false);
215 frontendHandle.protocol().tuneDVB_T(frequency,
223 hierarchy_information);
225 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
226 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
228 return frontendHandle.protocol().getEvent();
231 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){
233 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
237 frontendHandle.protocol().setNonBlock(false);
239 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
241 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
242 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
243 return frontendHandle.protocol().getEvent();
246 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency,
247 fe_spectral_inversion_t inversion,
248 unsigned int symbol_rate,
249 fe_code_rate_t fec_inner,
250 fe_modulation_t modulation
254 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
258 frontendHandle.protocol().setNonBlock(false);
260 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
261 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
262 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
264 return frontendHandle.protocol().getEvent();
268 prefix_ string senf::DVBSocketController::getTypeString(){
277 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
281 prefix_ unsigned int senf::DVBSocketController::bitErrorRate(){
282 return frontendHandle.protocol().bitErrorRate();
285 prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio(){
286 return frontendHandle.protocol().signalNoiseRatio();
289 prefix_ unsigned int senf::DVBSocketController::signalStrength(){
290 return frontendHandle.protocol().signalStrength();
293 prefix_ string senf::DVBSocketController::getTuneInfo(const string & conf){
294 const char* cConf = conf.c_str();
298 frontendHandle.protocol().setNonBlock(false);
299 uint16_t snr, signal;
300 uint32_t ber, uncorrected_blocks;
301 status = frontendHandle.protocol().status();
302 snr = frontendHandle.protocol().signalNoiseRatio();
303 signal = frontendHandle.protocol().signalStrength();
304 ber = frontendHandle.protocol().bitErrorRate();
305 uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
309 for(unsigned int i = 0; i < conf.size(); ++i){
314 info << "signal " << signal;
317 info << "snr " << snr;
320 info << "ber " << ber;
323 info << "unc " << uncorrected_blocks;
326 info << "status: " << status2String(status);
334 prefix_ string senf::DVBSocketController::status2String(fe_status_t status){
336 if (status & FE_HAS_LOCK)
337 return s += "HAS LOCK";
338 if (status & FE_HAS_CARRIER)
340 if (status & FE_HAS_VITERBI)
342 if (status & FE_HAS_SYNC)
344 if (status & FE_HAS_SIGNAL)
346 if (status & FE_TIMEDOUT)
348 if (status & FE_REINIT)
354 prefix_ void senf::DVBSocketController::setSectionFilter(unsigned short int pid,
359 unsigned int timeout)
361 sectionHandle.protocol().setSectionFilter(pid, timeout, flags, filter, mask, mode);
365 prefix_ void senf::DVBSocketController::setBufferSize(unsigned long size)
367 sectionHandle.protocol().setBufferSize(size);
370 prefix_ void senf::DVBSocketController::startFiltering()
372 sectionHandle.protocol().startFiltering();
375 prefix_ void senf::DVBSocketController::stopFiltering()
377 sectionHandle.protocol().stopFiltering();
380 prefix_ fe_type_t senf::DVBSocketController::getType(){
384 prefix_ void senf::DVBSocketController::readEvent(int event){
386 cb(frontendHandle.protocol().getEvent());
389 prefix_ void senf::DVBSocketController::initConsole(){
390 // binding functions to console
391 namespace kw = senf::console::kw;
392 dir.doc("DVB Controller");
394 dir.add("type", &DVBSocketController::getTypeString)
395 .doc("Shows actual type of card DVB-{T, S, C}");
397 dir.add("info", &DVBSocketController::getTuneInfo)
398 .doc("Returns a string which shows actual tuning status.\n\
399 \"S\" prints signal strength (in hex)\n\
400 \"s\" prints singal to noise ration (in hex)\n\
401 \"b\" prints bit error rate (in hex)\n\
402 \"u\" prints uncorrected blocks (in hex)\n\
403 \"f\" prints readable overal status e.g. \"Has Lock\"\n\n\
404 These characters can be used to form the output. Be aware, some\n\
405 features may not be supported be your current driver implementation\n\
406 and could end in throwing an exception!")
407 .arg("conf", "Ssbuf", kw::default_value = "Ssbuf");
409 dir.add("tune", &DVBSocketController::tuneToCMD)
410 .doc("tunes to channel listet in the configfile.")
411 .arg("channel", "channel to tune")
412 .arg("mode", "mode \"sync\" or \"async\"", kw::default_value = "async");
414 dir.add("buffersize", &DVBSocketController::setBufferSize)
415 .doc("Set the size of the circular buffer used for filtered data.")
416 .arg("size", "in byte");
418 dir.add("start", &DVBSocketController::startFiltering)
419 .doc("Starts filtering");
421 dir.add("stop", &DVBSocketController::setBufferSize)
422 .doc("Stops filtering");
424 dir.add("filter", &DVBSocketController::setSectionFilter)
425 .arg("pid", "pid to filter")
426 .arg("filter", "filter", kw::default_value = 62, kw::default_doc = "0x3e")
427 .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")
428 .arg("mask", "mask", kw::default_value = 0xff, kw::default_doc = "0xff")
429 .arg("mode", "mode", kw::default_value = 0, kw::default_doc = "0x00")
430 .arg("timeout", "timeout", kw::default_value = 0, kw::default_doc = "0x00")
431 .doc("Sets parameters for section filter.");
433 dir.add("stop", &DVBSocketController::setBufferSize)
434 .doc("Stops filtering");