1 #include "senf/Utils/Exception.hh"
2 #include "senf/Utils/Logger/Logger.hh"
3 #include "senf/Utils/membind.hh"
5 #include "DVBSocketController.hh"
12 senf::DVBSocketController::DVBSocketController(DVBFrontendHandle frontendHandle_, DVBDemuxSectionHandle sectionHandle_ , const Callback & cb_) :
14 frontendHandle( frontendHandle_ ),
15 sectionHandle( sectionHandle_ ),
16 type( frontendHandle.protocol().getInfo().type ),
19 event( "senf::DVBSocketController::readEvent", senf::membind(&DVBSocketController::readEvent, this), frontendHandle, senf::scheduler::FdEvent::EV_PRIO, false )
24 prefix_ senf::DVBSocketController::~DVBSocketController()
27 prefix_ void senf::DVBSocketController::tuneToCMD(const string & configLine, const string & mode){
28 struct dvb_frontend_parameters frontend;
31 // no valid configline, so it will be treaten like a channel name
32 if (configLine.find(":")==string::npos){
33 if (mode.c_str()[0]=='a')
36 tuneTo_sync(configLine);
39 // add psydo name to complete configline syntax
40 frontend = parser.getFrontendParam("foo:"+configLine);
42 if (mode.c_str()[0]=='a'){
45 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
48 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
51 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);
54 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
59 case FE_QPSK: if (mode.c_str()[0]=='a')
60 tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
63 tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
66 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);
69 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
74 prefix_ void senf::DVBSocketController::tuneTo(const string & channel)
76 struct dvb_frontend_parameters frontend;
78 string configLine = parser.getConfigLine(channel);
80 frontend = parser.getFrontendParam(configLine);
83 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
86 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
89 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);
92 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
96 prefix_ void senf::DVBSocketController::tuneDVB_T(unsigned int frequency,
97 fe_spectral_inversion_t inversion,
98 fe_bandwidth_t bandwidth,
99 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
100 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
101 fe_modulation_t constellation, /* modulation type (see above) */
102 fe_transmit_mode_t transmission_mode,
103 fe_guard_interval_t guard_interval,
104 fe_hierarchy_t hierarchy_information
108 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
112 frontendHandle.protocol().setNonBlock();
113 frontendHandle.protocol().tuneDVB_T(frequency,
121 hierarchy_information);
124 prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate){
126 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
130 frontendHandle.protocol().setNonBlock();
131 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
134 prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency,
135 fe_spectral_inversion_t inversion,
136 unsigned int symbol_rate,
137 fe_code_rate_t fec_inner,
138 fe_modulation_t modulation
142 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
146 frontendHandle.protocol().setNonBlock();
148 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
151 prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(const string & channel)
153 struct dvb_frontend_parameters frontend;
154 dvb_frontend_event ev;
155 string configLine = parser.getConfigLine(channel);
157 frontend = parser.getFrontendParam(configLine);
160 ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
163 ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
166 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);
169 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
174 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(unsigned int frequency,
175 fe_spectral_inversion_t inversion,
176 fe_bandwidth_t bandwidth,
177 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
178 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
179 fe_modulation_t constellation, /* modulation type (see above) */
180 fe_transmit_mode_t transmission_mode,
181 fe_guard_interval_t guard_interval,
182 fe_hierarchy_t hierarchy_information
186 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
190 frontendHandle.protocol().setNonBlock(false);
192 frontendHandle.protocol().tuneDVB_T(frequency,
200 hierarchy_information);
202 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
203 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
205 return frontendHandle.protocol().getEvent();
208 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){
210 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
214 frontendHandle.protocol().setNonBlock(false);
216 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
218 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
219 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
220 return frontendHandle.protocol().getEvent();
223 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency,
224 fe_spectral_inversion_t inversion,
225 unsigned int symbol_rate,
226 fe_code_rate_t fec_inner,
227 fe_modulation_t modulation
231 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
235 frontendHandle.protocol().setNonBlock(false);
237 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
238 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
239 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
241 return frontendHandle.protocol().getEvent();
245 prefix_ string senf::DVBSocketController::getTypeString(){
254 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
258 prefix_ unsigned int senf::DVBSocketController::bitErrorRate(){
259 return frontendHandle.protocol().bitErrorRate();
262 prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio(){
263 return frontendHandle.protocol().signalNoiseRatio();
266 prefix_ unsigned int senf::DVBSocketController::signalStrength(){
267 return frontendHandle.protocol().signalStrength();
270 prefix_ string senf::DVBSocketController::getTuneInfo(const string & conf){
271 const char* cConf = conf.c_str();
275 frontendHandle.protocol().setNonBlock(false);
276 uint16_t snr, signal;
277 uint32_t ber, uncorrected_blocks;
278 status = frontendHandle.protocol().status();
279 snr = frontendHandle.protocol().signalNoiseRatio();
280 signal = frontendHandle.protocol().signalStrength();
281 ber = frontendHandle.protocol().bitErrorRate();
282 uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
286 for(unsigned int i = 0; i < conf.size(); ++i){
291 info << "signal " << signal;
294 info << "snr " << snr;
297 info << "ber " << ber;
300 info << "unc " << uncorrected_blocks;
303 info << "status: " << status2String(status);
311 prefix_ string senf::DVBSocketController::status2String(fe_status_t status){
313 if (status & FE_HAS_LOCK)
314 return s += "HAS LOCK";
315 if (status & FE_HAS_CARRIER)
317 if (status & FE_HAS_VITERBI)
319 if (status & FE_HAS_SYNC)
321 if (status & FE_HAS_SIGNAL)
323 if (status & FE_TIMEDOUT)
325 if (status & FE_REINIT)
331 prefix_ void senf::DVBSocketController::setSectionFilter(unsigned short int pid,
336 unsigned int timeout)
338 sectionHandle.protocol().setSectionFilter(pid, timeout, flags, filter, mask, mode);
342 prefix_ void senf::DVBSocketController::setBufferSize(unsigned long size)
344 sectionHandle.protocol().setBufferSize(size);
347 prefix_ void senf::DVBSocketController::startFiltering()
349 sectionHandle.protocol().startFiltering();
352 prefix_ void senf::DVBSocketController::stopFiltering()
354 sectionHandle.protocol().stopFiltering();
357 prefix_ fe_type_t senf::DVBSocketController::getType(){
361 prefix_ void senf::DVBSocketController::readEvent(int event){
363 cb(frontendHandle.protocol().getEvent());
366 prefix_ void senf::DVBSocketController::initConsole(){
367 // binding functions to console
368 namespace kw = senf::console::kw;
369 dir.doc("DVB Controller");
371 dir.add("type", &DVBSocketController::getTypeString)
372 .doc("Shows actual type of card DVB-{T, S, C}");
374 dir.add("info", &DVBSocketController::getTuneInfo)
375 .doc("Returns a string which shows actual tuning status.\n\
376 \"S\" prints signal strength (in hex)\n\
377 \"s\" prints singal to noise ration (in hex)\n\
378 \"b\" prints bit error rate (in hex)\n\
379 \"u\" prints uncorrected blocks (in hex)\n\
380 \"f\" prints readable overal status e.g. \"Has Lock\"\n\n\
381 These characters can be used to form the output. Be aware, some\n\
382 features may not be supported be your current driver implementation\n\
383 and could end in throwing an exception!")
384 .arg("conf", "Ssbuf", kw::default_value = "Ssbuf");
386 dir.add("tune", &DVBSocketController::tuneToCMD)
387 .doc("tunes to channel listet in the configfile.")
388 .arg("channel", "channel to tune")
389 .arg("mode", "mode \"sync\" or \"async\"", kw::default_value = "async");
391 dir.add("buffersize", &DVBSocketController::setBufferSize)
392 .doc("Set the size of the circular buffer used for filtered data.")
393 .arg("size", "in byte");
395 dir.add("start", &DVBSocketController::startFiltering)
396 .doc("Starts filtering");
398 dir.add("stop", &DVBSocketController::setBufferSize)
399 .doc("Stops filtering");
401 dir.add("filter", &DVBSocketController::setSectionFilter)
402 .arg("pid", "pid to filter")
403 .arg("filter", "filter", kw::default_value = 62)
404 .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)
405 .arg("mask", "mask", kw::default_value = 0xff)
406 .arg("mode", "mode", kw::default_value = 0)
407 .arg("timeout", "timeout", kw::default_value = 0)
408 .doc("Sets parameters for section filter.");
410 dir.add("stop", &DVBSocketController::setBufferSize)
411 .doc("Stops filtering");