4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
6 // The contents of this file are subject to the Fraunhofer FOKUS Public License
7 // Version 1.0 (the "License"); you may not use this file except in compliance
8 // with the License. You may obtain a copy of the License at
9 // http://senf.berlios.de/license.html
11 // The Fraunhofer FOKUS Public License Version 1.0 is based on,
12 // but modifies the Mozilla Public License Version 1.1.
13 // See the full license text for the amendments.
15 // Software distributed under the License is distributed on an "AS IS" basis,
16 // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
17 // for the specific language governing rights and limitations under the License.
19 // The Original Code is Fraunhofer FOKUS code.
21 // The Initial Developer of the Original Code is Fraunhofer-Gesellschaft e.V.
22 // (registered association), Hansastraße 27 c, 80686 Munich, Germany.
23 // All Rights Reserved.
26 // Anton Gillert <atx@berlios.de>
28 \brief DVBSocketController non-inline non-template implementation */
30 #include "DVBSocketController.hh"
34 #include <senf/Utils/Exception.hh>
35 #include <senf/Utils/Logger/Logger.hh>
36 #include <senf/Utils/membind.hh>
37 #include <senf/Utils/Console/ParsedCommand.hh>
38 #include <boost/shared_ptr.hpp>
39 #include "DVBProtocolWrapper.hh"
42 //-/////////////////////////////////////////////////////////////////////////////////////////////////
44 unsigned int senf::DVBSocketController::controllerNr(0);
46 senf::DVBSocketController::DVBSocketController(DVBFrontendHandle frontendHandle_,
49 frontendHandle( frontendHandle_ ),
50 type( frontendHandle.protocol().getInfo().type ),
55 event( "senf::DVBSocketController::readEvent",
56 senf::membind(&DVBSocketController::readEvent, this), frontendHandle,
57 senf::scheduler::FdEvent::EV_PRIO, false )
62 prefix_ senf::DVBSocketController::~DVBSocketController()
65 prefix_ senf::DVBDemuxSectionHandle
66 senf::DVBSocketController::createDVBDemuxSectionHandle(int adapternumber, int demuxnumber,
69 DVBDemuxSectionHandle sectionHandle(adapternumber, demuxnumber);
71 this->addToConsole(sectionHandle);
76 prefix_ senf::DVBDemuxPESHandle
77 senf::DVBSocketController::createDVBDemuxPESHandle(int adapternumber, int demuxnumber,
80 DVBDemuxPESHandle pesHandle(adapternumber, demuxnumber);
82 this->addToConsole(pesHandle);
87 prefix_ void senf::DVBSocketController::addToConsole(senf::DVBDemuxSectionHandle sh)
89 boost::shared_ptr<DVBSectionProtocolWrapper> wrap(new DVBSectionProtocolWrapper(sh));
90 sh.protocol().addWrapper(wrap);
91 dir.node().add("section" + senf::str(sectionNr), wrap->dir);
95 prefix_ void senf::DVBSocketController::addToConsole(senf::DVBDemuxPESHandle sh)
97 boost::shared_ptr<DVBPESProtocolWrapper> wrap(new DVBPESProtocolWrapper(sh));
98 sh.protocol().addWrapper(wrap);
99 dir.node().add("pes"+ senf::str(pesNr), wrap->dir);
103 prefix_ void senf::DVBSocketController::tuneToCMD(std::string const & input, std::string const & mode)
105 struct dvb_frontend_parameters frontend;
107 // no valid configline, so it will be treaten like a channel name
108 if (input.find(":") == std::string::npos)
110 if (mode.c_str()[0]=='a')
116 // add psydo name "foo" to complete configline syntax
117 frontend = parser.getFrontendParam("foo:"+input);
119 if (mode.c_str()[0]=='a') {
122 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate,
123 frontend.u.qpsk.fec_inner);
126 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
127 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
130 tuneDVB_T(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
131 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
132 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
133 frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
136 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
142 tuneDVB_S_sync(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate,
143 frontend.u.qpsk.fec_inner);
146 tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
147 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
150 tuneDVB_T_sync(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
151 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
152 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
153 frontend.u.ofdm.guard_interval,
154 frontend.u.ofdm.hierarchy_information);
157 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
162 prefix_ void senf::DVBSocketController::tuneTo(std::string const & channel)
164 struct dvb_frontend_parameters frontend;
166 std::string configLine = parser.getConfigLine(channel);
168 frontend = parser.getFrontendParam(configLine);
171 tuneDVB_S(frontend.frequency, frontend.inversion, frontend.u.qpsk.symbol_rate,
172 frontend.u.qpsk.fec_inner);
175 tuneDVB_C(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
176 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
179 tuneDVB_T(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
180 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
181 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
182 frontend.u.ofdm.guard_interval, frontend.u.ofdm.hierarchy_information);
185 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
189 prefix_ void senf::DVBSocketController::tuneDVB_T(unsigned int frequency,
190 fe_spectral_inversion_t inversion,
191 fe_bandwidth_t bandwidth,
192 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
193 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
194 fe_modulation_t constellation, /* modulation type (see above) */
195 fe_transmit_mode_t transmission_mode,
196 fe_guard_interval_t guard_interval,
197 fe_hierarchy_t hierarchy_information
201 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
202 << getTypeString() << " for this operation you need a DVB-T Card!";
206 frontendHandle.protocol().setNonBlock();
207 frontendHandle.protocol().tuneDVB_T(frequency,
215 hierarchy_information);
218 prefix_ void senf::DVBSocketController::tuneDVB_S(unsigned int frequency,
219 fe_spectral_inversion_t inversion,
220 unsigned int symbole_rate,
221 fe_code_rate_t code_rate)
224 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
225 << getTypeString() << " for this operation you need a DVB-S Card!";
229 frontendHandle.protocol().setNonBlock();
230 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
233 prefix_ void senf::DVBSocketController::tuneDVB_C(unsigned int frequency,
234 fe_spectral_inversion_t inversion,
235 unsigned int symbol_rate,
236 fe_code_rate_t fec_inner,
237 fe_modulation_t modulation
241 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
242 << getTypeString() << " for this operation you need a DVB-C Card!";
246 frontendHandle.protocol().setNonBlock();
248 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
251 prefix_ dvb_frontend_event senf::DVBSocketController::tuneTo_sync(std::string const & channel)
253 struct dvb_frontend_parameters frontend;
254 dvb_frontend_event ev;
255 std::string configLine = parser.getConfigLine(channel);
257 frontend = parser.getFrontendParam(configLine);
260 ev = tuneDVB_S_sync(frontend.frequency, frontend.inversion,
261 frontend.u.qpsk.symbol_rate, frontend.u.qpsk.fec_inner);
264 ev = tuneDVB_C_sync(frontend.frequency, frontend.inversion, frontend.u.qam.symbol_rate,
265 frontend.u.qam.fec_inner, frontend.u.qam.modulation);
268 ev = tuneDVB_T_sync(frontend.frequency, frontend.inversion, frontend.u.ofdm.bandwidth,
269 frontend.u.ofdm.code_rate_HP, frontend.u.ofdm.code_rate_LP,
270 frontend.u.ofdm.constellation, frontend.u.ofdm.transmission_mode,
271 frontend.u.ofdm.guard_interval,
272 frontend.u.ofdm.hierarchy_information);
275 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
280 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_T_sync(unsigned int frequency,
281 fe_spectral_inversion_t inversion,
282 fe_bandwidth_t bandwidth,
283 fe_code_rate_t code_rate_HP, /* high priority stream code rate */
284 fe_code_rate_t code_rate_LP, /* low priority stream code rate */
285 fe_modulation_t constellation, /* modulation type (see above) */
286 fe_transmit_mode_t transmission_mode,
287 fe_guard_interval_t guard_interval,
288 fe_hierarchy_t hierarchy_information
292 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
293 << getTypeString() << " for this operation you need a DVB-T Card!";
297 frontendHandle.protocol().setNonBlock(false);
299 frontendHandle.protocol().tuneDVB_T(frequency,
307 hierarchy_information);
309 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
310 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
312 return frontendHandle.protocol().getEvent();
315 prefix_ dvb_frontend_event
316 senf::DVBSocketController::tuneDVB_S_sync(unsigned int frequency,
317 fe_spectral_inversion_t inversion,
318 unsigned int symbole_rate, fe_code_rate_t code_rate)
321 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
322 << getTypeString() << " for this operation you need a DVB-S Card!";
326 frontendHandle.protocol().setNonBlock(false);
328 frontendHandle.protocol().tuneDVB_S(frequency, inversion, symbole_rate, code_rate);
330 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
331 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
332 return frontendHandle.protocol().getEvent();
335 prefix_ dvb_frontend_event senf::DVBSocketController::tuneDVB_C_sync(unsigned int frequency,
336 fe_spectral_inversion_t inversion,
337 unsigned int symbol_rate,
338 fe_code_rate_t fec_inner,
339 fe_modulation_t modulation
343 SENF_THROW_SYSTEM_EXCEPTION("Type of card is: ")
344 << getTypeString() << " for this operation you need a DVB-C Card!";
348 frontendHandle.protocol().setNonBlock(false);
350 frontendHandle.protocol().tuneDVB_C(frequency, inversion, symbol_rate, fec_inner, modulation);
351 if (!frontendHandle.waitOOBReadable(senf::ClockService::seconds(2)))
352 SENF_THROW_SYSTEM_EXCEPTION("Could not tune to channel!");
354 return frontendHandle.protocol().getEvent();
358 prefix_ std::string senf::DVBSocketController::getTypeString()
368 SENF_THROW_SYSTEM_EXCEPTION("Could not determine type of card.");
372 prefix_ unsigned int senf::DVBSocketController::bitErrorRate()
374 return frontendHandle.protocol().bitErrorRate();
377 prefix_ unsigned int senf::DVBSocketController::signalToNoiseRatio()
379 return frontendHandle.protocol().signalNoiseRatio();
382 prefix_ unsigned int senf::DVBSocketController::signalStrength()
384 return frontendHandle.protocol().signalStrength();
387 prefix_ std::string senf::DVBSocketController::getTuneInfo(std::string const & conf)
389 const char* cConf = conf.c_str();
390 std::stringstream info;
393 frontendHandle.protocol().setNonBlock(false);
394 uint16_t snr, signal;
395 uint32_t ber, uncorrected_blocks;
396 status = frontendHandle.protocol().status();
397 snr = frontendHandle.protocol().signalNoiseRatio();
398 signal = frontendHandle.protocol().signalStrength();
399 ber = frontendHandle.protocol().bitErrorRate();
400 uncorrected_blocks = frontendHandle.protocol().uncorrectedBlocks();
404 for (unsigned int i = 0; i < conf.size(); ++i) {
409 info << "signal " << signal;
412 info << "snr " << snr;
415 info << "ber " << ber;
418 info << "unc " << uncorrected_blocks;
421 info << "status: " << status2String(status);
430 prefix_ std::string senf::DVBSocketController::status2String(fe_status_t status)
433 if (status & FE_HAS_LOCK)
434 return s += "HAS LOCK";
435 if (status & FE_HAS_CARRIER)
437 if (status & FE_HAS_VITERBI)
439 if (status & FE_HAS_SYNC)
441 if (status & FE_HAS_SIGNAL)
443 if (status & FE_TIMEDOUT)
445 if (status & FE_REINIT)
451 prefix_ fe_type_t senf::DVBSocketController::getType()
456 prefix_ void senf::DVBSocketController::readEvent(int event)
459 cb(frontendHandle.protocol().getEvent());
462 prefix_ void senf::DVBSocketController::initConsole()
464 namespace fty = console::factory;
465 namespace kw = console::kw;
467 dir.doc("DVB Controller " + controllerNr);
470 dir.add("type", fty::Command(&DVBSocketController::getTypeString, this)
471 .doc("Shows actual type of card DVB-{T, S, C}") );
473 dir.add("info", fty::Command(&DVBSocketController::getTuneInfo, this)
474 .doc("Returns a string which shows actual tuning status.\n"
475 "'S' prints signal strength (in hex)\n"
476 "'s' prints singal to noise ration (in hex)\n"
477 "'b' prints bit error rate (in hex)\n"
478 "'u' prints uncorrected blocks (in hex)\n"
479 "'f' prints readable overal status e.g. 'Has Lock'\n\n"
480 "These characters can be used to form the output. Be aware, some\n"
481 "features may not be supported be your current driver implementation\n"
482 "and could end in throwing an exception!")
483 .arg("conf", "Ssbuf", kw::default_value = "Ssbuf") );
485 dir.add("tune", fty::Command(&DVBSocketController::tuneToCMD, this)
486 .doc("tunes to channel listet in the configfile.")
487 .arg("channel", "channel to tune")
488 .arg("mode", "mode 'sync' or 'async'", kw::default_value = "async") );
491 //-/////////////////////////////////////////////////////////////////////////////////////////////////
498 // c-file-style: "senf"
499 // indent-tabs-mode: nil
500 // ispell-local-dictionary: "american"
501 // compile-command: "scons -u test"
502 // comment-column: 40