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 SENF_LOG((senf::log::MESSAGE) ("async: configline found: " << channel) );
87 frontend = parser.getFrontendParam(configLine);
90 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
93 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
96 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);
99 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
103 prefix_ void senf::DVBSocketController::tuneDVB_T(unsigned int frequency,
104 fe_spectral_inversion_t inversion,
105 fe_bandwidth_t bandwidth,
106 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
107 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
108 fe_modulation_t constellation, /* modulation type (see above) */
109 fe_transmit_mode_t transmission_mode,
110 fe_guard_interval_t guard_interval,
111 fe_hierarchy_t hierarchy_information
115 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
117 frontendHandle.protocol().setNonBlock();
118 frontendHandle.protocol().tuneDVB_T(frequency,
126 hierarchy_information);
129 prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency, fe_spectral_inversion_t inversion, unsigned int symbole_rate, fe_code_rate_t code_rate){
131 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
133 frontendHandle.protocol().setNonBlock();
134 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
137 prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency,
138 fe_spectral_inversion_t inversion,
139 unsigned int symbol_rate,
140 fe_code_rate_t fec_inner,
141 fe_modulation_t modulation
145 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
148 frontendHandle.protocol().setNonBlock();
150 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
153 prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(const string & channel)
155 struct dvb_frontend_parameters frontend;
156 dvb_frontend_event ev;
157 string configLine = parser.getConfigLine(channel);
159 SENF_LOG((senf::log::MESSAGE) ("sync: configline found: " << channel) );
160 frontend = parser.getFrontendParam(configLine);
163 ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
166 ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate, frontend.u.qam.fec_inner, frontend.u.qam.modulation);
169 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);
172 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
177 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(unsigned int frequency,
178 fe_spectral_inversion_t inversion,
179 fe_bandwidth_t bandwidth,
180 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
181 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
182 fe_modulation_t constellation, /* modulation type (see above) */
183 fe_transmit_mode_t transmission_mode,
184 fe_guard_interval_t guard_interval,
185 fe_hierarchy_t hierarchy_information
189 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-T Card!";
191 frontendHandle.protocol().setNonBlock(false);
193 frontendHandle.protocol().tuneDVB_T(frequency,
201 hierarchy_information);
203 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
204 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
206 return frontendHandle.protocol().getEvent();
209 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){
211 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-S Card!";
213 frontendHandle.protocol().setNonBlock(false);
214 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
216 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
217 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
218 return frontendHandle.protocol().getEvent();
221 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency,
222 fe_spectral_inversion_t inversion,
223 unsigned int symbol_rate,
224 fe_code_rate_t fec_inner,
225 fe_modulation_t modulation
229 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ") << getTypeString() << " for this operation you need a DVB-C Card!";
232 frontendHandle.protocol().setNonBlock(false);
233 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
234 if(!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
235 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
237 return frontendHandle.protocol().getEvent();
241 prefix_ string senf::DVBSocketController::getTypeString(){
250 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
254 prefix_ unsigned int senf::DVBSocketController::bitErrorRate(){
255 return frontendHandle.protocol().bitErrorRate();
258 prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio(){
259 return frontendHandle.protocol().signalNoiseRatio();
262 prefix_ unsigned int senf::DVBSocketController::signalStrength(){
263 return frontendHandle.protocol().signalStrength();
266 prefix_ string senf::DVBSocketController::getTuneInfo(const string & conf){
267 const char* cConf = conf.c_str();
271 uint16_t snr, signal;
272 uint32_t ber, uncorrected_blocks;
273 status = frontendHandle.protocol().status();
274 snr = frontendHandle.protocol().signalNoiseRatio();
275 signal = frontendHandle.protocol().signalStrength();
276 ber = frontendHandle.protocol().bitErrorRate();
277 uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
281 for(unsigned int i = 0; i < conf.size(); ++i){
284 info << " | signal " << signal;
287 info << " | snr " << snr;
290 info << " | ber " << ber;
293 info << " | unc " << uncorrected_blocks;
296 info << " | status: " << status2String(status);
304 prefix_ string senf::DVBSocketController::status2String(fe_status_t status){
306 if (status & FE_HAS_LOCK)
307 return s += "|HAS LOCK";
308 if (status & FE_HAS_CARRIER)
310 if (status & FE_HAS_VITERBI)
312 if (status & FE_HAS_SYNC)
314 if (status & FE_HAS_SIGNAL)
316 if (status & FE_TIMEDOUT)
318 if (status & FE_REINIT)
324 prefix_ void senf::DVBSocketController::setSectionFilter(unsigned short int pid,
325 unsigned char filter,
329 unsigned int timeout)
331 sectionHandle.protocol().setSectionFilter(pid, timeout, flags, filter, mask, mode);
335 prefix_ void senf::DVBSocketController::setBufferSize(unsigned long size)
337 sectionHandle.protocol().setBufferSize(size);
340 prefix_ void senf::DVBSocketController::startFiltering()
342 sectionHandle.protocol().startFiltering();
345 prefix_ void senf::DVBSocketController::stopFiltering()
347 sectionHandle.protocol().stopFiltering();
351 prefix_ fe_type_t senf::DVBSocketController::getType(){
355 prefix_ void senf::DVBSocketController::readEvent(int event){
356 cb(frontendHandle.protocol().getEvent());
359 prefix_ void senf::DVBSocketController::initConsole(){
360 // binding functions to console
361 namespace kw = senf::console::kw;
362 dir.doc("DVB Controller");
364 dir.add("type", &DVBSocketController::getTypeString)
365 .doc("Shows actual type of card DVB-{T, S, C}");
367 dir.add("info", &DVBSocketController::getTuneInfo)
368 .doc("Returns a string which shows actual tuning status.\n\
369 \"S\" prints signal strength (in hex)\n\
370 \"s\" prints singal to noise ration (in hex)\n\
371 \"b\" prints bit error rate (in hex)\n\
372 \"u\" prints uncorrected blocks (in hex)\n\
373 \"f\" prints readable overal status e.g. \"Has Lock\"\n\n\
374 These characters can be used to form the output. Be aware, some\n\
375 features may not be supported be your current driver implementation\n\
376 and could end in throwing an exception!")
377 .arg("conf", "Ssbuf", kw::default_value = "Ssbuf");
379 dir.add("tuneTo", &DVBSocketController::tuneToCMD)
380 .doc("tunes to channel listet in the configfile.")
381 .arg("channel", "channel to tune")
382 .arg("mode", "mode \"sync\" or \"async\"", kw::default_value = "async");
384 dir.add("buffersize", &DVBSocketController::setBufferSize)
385 .doc("Set the size of the circular buffer used for filtered data.")
386 .arg("size", "in byte");
388 dir.add("start", &DVBSocketController::startFiltering)
389 .doc("Starts filtering");
391 dir.add("stop", &DVBSocketController::setBufferSize)
392 .doc("Stops filtering");
394 dir.add("filter", &DVBSocketController::setSectionFilter)
395 .arg("pid", "pid to filter")
396 .arg("filter", "filter", kw::default_value = 62)
397 .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)
398 .arg("mask", "mask", kw::default_value = 0xff)
399 .arg("mode", "mode", kw::default_value = 0)
400 .arg("timeout", "timeout", kw::default_value = 0)
401 .doc("Sets parameters for section filter.");
403 dir.add("stop", &DVBSocketController::setBufferSize)
404 .doc("Stops filtering");