1 #include "../../../Utils/Exception.hh"
2 #include "../../../Utils/Logger/Logger.hh"
3 #include <../../../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_ string 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'){
35 return "async readConfFile";
38 tuneTo_sync(configLine);
39 return "sync readConfFile";
43 // add psydo name to complete configline syntax
44 frontend = parser.getFrontendParam("foo:"+configLine);
46 if (mode.c_str()[0]=='a'){
49 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
52 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
55 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);
58 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
60 return "async get directly";
64 case FE_QPSK: if (mode.c_str()[0]=='a')
65 tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
68 tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
71 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);
74 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
76 return "sync get directly";
80 prefix_ void senf::DVBSocketController::tuneTo(const string & channel)
82 struct dvb_frontend_parameters frontend;
84 string configLine = parser.getConfigLine(channel);
86 frontend = parser.getFrontendParam(configLine);
89 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
92 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
95 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);
98 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
102 prefix_ void senf::DVBSocketController::tuneDVB_T(unsigned int frequency,
103 fe_spectral_inversion_t inversion,
104 fe_bandwidth_t bandwidth,
105 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
106 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
107 fe_modulation_t constellation, /* modulation type (see above) */
108 fe_transmit_mode_t transmission_mode,
109 fe_guard_interval_t guard_interval,
110 fe_hierarchy_t hierarchy_information
114 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
116 frontendHandle.protocol().setNonBlock();
117 frontendHandle.protocol().tuneDVB_T(frequency,
125 hierarchy_information);
128 prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate){
130 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
132 frontendHandle.protocol().setNonBlock();
133 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
136 prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency,
137 fe_spectral_inversion_t inversion,
138 unsigned int symbol_rate,
139 fe_code_rate_t fec_inner,
140 fe_modulation_t modulation
144 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
147 frontendHandle.protocol().setNonBlock();
149 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
152 prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(const string & channel)
154 struct dvb_frontend_parameters frontend;
155 dvb_frontend_event ev;
156 string configLine = parser.getConfigLine(channel);
158 frontend = parser.getFrontendParam(configLine);
161 ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
164 ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
167 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);
170 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
175 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(unsigned int frequency,
176 fe_spectral_inversion_t inversion,
177 fe_bandwidth_t bandwidth,
178 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
179 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
180 fe_modulation_t constellation, /* modulation type (see above) */
181 fe_transmit_mode_t transmission_mode,
182 fe_guard_interval_t guard_interval,
183 fe_hierarchy_t hierarchy_information
187 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
189 frontendHandle.protocol().setNonBlock(false);
191 frontendHandle.protocol().tuneDVB_T(frequency,
199 hierarchy_information);
201 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
202 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
204 return frontendHandle.protocol().getEvent();
207 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){
209 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
211 frontendHandle.protocol().setNonBlock(false);
212 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
214 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
215 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
216 return frontendHandle.protocol().getEvent();
219 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency,
220 fe_spectral_inversion_t inversion,
221 unsigned int symbol_rate,
222 fe_code_rate_t fec_inner,
223 fe_modulation_t modulation
227 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
230 frontendHandle.protocol().setNonBlock(false);
231 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
232 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
233 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
235 return frontendHandle.protocol().getEvent();
239 prefix_ string senf::DVBSocketController::getTypeString(){
248 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
252 prefix_ unsigned int senf::DVBSocketController::bitErrorRate(){
253 return frontendHandle.protocol().bitErrorRate();
256 prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio(){
257 return frontendHandle.protocol().signalNoiseRatio();
260 prefix_ unsigned int senf::DVBSocketController::signalStrength(){
261 return frontendHandle.protocol().signalStrength();
264 prefix_ string senf::DVBSocketController::getTuneInfo(const string & conf){
265 const char* cConf = conf.c_str();
269 uint16_t snr, signal;
270 uint32_t ber, uncorrected_blocks;
271 status = frontendHandle.protocol().status();
272 snr = frontendHandle.protocol().signalNoiseRatio();
273 signal = frontendHandle.protocol().signalStrength();
274 ber = frontendHandle.protocol().bitErrorRate();
275 uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
279 for(unsigned int i = 0; i < conf.size(); ++i){
282 info << " | signal " << signal;
285 info << " | snr " << snr;
288 info << " | ber " << ber;
291 info << " | unc " << uncorrected_blocks;
294 info << " | status: " << status2String(status);
302 prefix_ string senf::DVBSocketController::status2String(fe_status_t status){
304 if (status & FE_HAS_LOCK)
305 return s += "|HAS LOCK";
306 if (status & FE_HAS_CARRIER)
308 if (status & FE_HAS_VITERBI)
310 if (status & FE_HAS_SYNC)
312 if (status & FE_HAS_SIGNAL)
314 if (status & FE_TIMEDOUT)
316 if (status & FE_REINIT)
322 prefix_ void senf::DVBSocketController::setSectionFilter(unsigned short int pid,
323 unsigned char filter,
327 unsigned int timeout)
329 sectionHandle.protocol().setSectionFilter(pid, timeout, flags, filter, mask, mode);
333 prefix_ void senf::DVBSocketController::setBufferSize(unsigned long size)
335 sectionHandle.protocol().setBufferSize(size);
338 prefix_ void senf::DVBSocketController::startFiltering()
340 sectionHandle.protocol().startFiltering();
343 prefix_ void senf::DVBSocketController::stopFiltering()
345 sectionHandle.protocol().stopFiltering();
349 prefix_ fe_type_t senf::DVBSocketController::getType(){
353 prefix_ void senf::DVBSocketController::readEvent(int event){
354 cb(frontendHandle.protocol().getEvent());
357 prefix_ void senf::DVBSocketController::initConsole(){
358 // binding functions to console
359 namespace kw = senf::console::kw;
360 dir.doc("DVB Controller");
362 dir.add("type", &DVBSocketController::getTypeString)
363 .doc("Shows actual type of card DVB-{T, S, C}");
365 dir.add("info", &DVBSocketController::getTuneInfo)
366 .doc("Returns a string which shows actual tuning status.\n\
367 \"S\" prints signal strength (in hex)\n\
368 \"s\" prints singal to noise ration (in hex)\n\
369 \"b\" prints bit error rate (in hex)\n\
370 \"u\" prints uncorrected blocks (in hex)\n\
371 \"f\" prints readable overal status e.g. \"Has Lock\"\n\n\
372 These characters can be used to form the output. Be aware, some\n\
373 features may not be supported be your current driver implementation\n\
374 and could end in throwing an exception!")
375 .arg("conf", "Ssbuf", kw::default_value = "Ssbuf");
377 dir.add("tuneTo", &DVBSocketController::tuneToCMD)
378 .doc("tunes to channel listet in the configfile.")
379 .arg("channel", "channel to tune")
380 .arg("mode", "mode \"sync\" or \"async\"", kw::default_value = "async");
382 dir.add("buffersize", &DVBSocketController::setBufferSize)
383 .doc("Set the size of the circular buffer used for filtered data.")
384 .arg("size", "in byte");
386 dir.add("start", &DVBSocketController::startFiltering)
387 .doc("Starts filtering");
389 dir.add("stop", &DVBSocketController::setBufferSize)
390 .doc("Stops filtering");
392 dir.add("filter", &DVBSocketController::setSectionFilter)
393 .arg("pid", "pid to filter")
394 .arg("filter", "filter", kw::default_value = 62)
395 .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)
396 .arg("mask", "mask", kw::default_value = 0xff)
397 .arg("mode", "mode", kw::default_value = 0)
398 .arg("timeout", "timeout", kw::default_value = 0)
399 .doc("Sets parameters for section filter.");
401 dir.add("stop", &DVBSocketController::setBufferSize)
402 .doc("Stops filtering");