Utils/Logger: Implement direct syslog-via-UDP target
[senf.git] / Socket / Protocols / DVB / DVBFrontendHandle.cc
1 // $Id$
2 //
3 // Copyright (C) 2007
4 // Fraunhofer Institute for Open Communication Systems (FOKUS)
5 // Competence Center NETwork research (NET), St. Augustin, GERMANY
6 //     Thorsten Horstmann <tho@berlios.de>
7 //
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.
12 //
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.
17 //
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.
22
23 /** \file
24     \brief DVBFrontendHandle non-inline non-template implementation */
25
26 #include "DVBFrontendHandle.hh"
27 //#include "DVBFrontendHandle.ih"
28
29 // Custom includes
30 #include <boost/format.hpp>
31 #include <sys/socket.h>
32 #include <sys/ioctl.h>
33 #include <fcntl.h>
34 #include "../../../Utils/Exception.hh"
35 #include <poll.h>
36 #include <unistd.h>
37 #include <fcntl.h>
38
39
40 //#include "DVBFrontendHandle.mpp"
41 #define prefix_
42 ///////////////////////////////cc.p////////////////////////////////////////
43
44 ///////////////////////////////////////////////////////////////////////////
45 // senf::DVBFrontendHandle
46 using namespace std;
47
48 prefix_ void senf::DVBFrontendSocketProtocol::init_client(unsigned const short adapter,unsigned const short device)
49 {
50     string devFrontend = str( boost::format("/dev/dvb/adapter%d/frontend%d") % adapter % device);
51     int f = open(devFrontend.c_str(), O_RDONLY | O_NONBLOCK);
52     if (f < 0)
53         SENF_THROW_SYSTEM_EXCEPTION("")<< "Could not open frontend device of DVB adapter " << devFrontend << ".";
54     fd(f);
55     
56     // later there will be a decision between waitTune and asyncTune
57     cb2_X_Tune = boost::bind(&senf::DVBFrontendSocketProtocol::waitTune, this, _1);
58
59     struct dvb_frontend_info info;
60     ioctl(fd(), FE_GET_INFO, &info);
61
62 }
63
64 prefix_ unsigned senf::DVBFrontendSocketProtocol::available()
65     const
66 {
67     return 0;
68 }
69
70 prefix_ bool senf::DVBFrontendSocketProtocol::eof()
71     const
72 {
73     return false;
74 }
75
76 prefix_ struct dvb_frontend_event senf::DVBFrontendSocketProtocol::tune(const struct dvb_frontend_parameters & frontend){
77     return cb2_X_Tune(frontend);
78 }
79 prefix_ struct dvb_frontend_event senf::DVBFrontendSocketProtocol::waitTune(const struct dvb_frontend_parameters & frontend) {
80     // tuning
81     if ( ::ioctl(fd(), FE_SET_FRONTEND, &frontend) ) 
82         SENF_THROW_SYSTEM_EXCEPTION("") << "Could not write on frontend device. Socket should initialized with write permissions.";
83     // getting event
84     struct dvb_frontend_event ev;
85     ::ioctl(fd(), FE_GET_EVENT, &ev);
86     
87     return ev;
88 }
89
90 prefix_ struct dvb_frontend_event senf::DVBFrontendSocketProtocol::asyncTune(const struct dvb_frontend_parameters & frontend){
91     // tuning
92     if ( ::ioctl(fd(), FE_SET_FRONTEND, &frontend) ) 
93     SENF_THROW_SYSTEM_EXCEPTION("") << "Could not write on frontend device. Socket should initialized with write permissions.";
94       
95     // do something async here 
96     struct dvb_frontend_event ev;
97     return ev;
98 }
99
100 prefix_ void senf::DVBFrontendSocketProtocol::tuneDVB_T(unsigned int frequency, 
101         fe_spectral_inversion_t inversion,
102         fe_bandwidth_t bandwidth, 
103         fe_code_rate_t code_rate_HP, /* high priority stream code rate */
104         fe_code_rate_t code_rate_LP, /* low priority stream code rate */
105         fe_modulation_t constellation, /* modulation type */
106         fe_transmit_mode_t transmission_mode, 
107         fe_guard_interval_t guard_interval,
108         fe_hierarchy_t hierarchy_information
109         )
110 {
111     struct dvb_ofdm_parameters ofdm; /* DVB-T Parameters */
112     struct dvb_frontend_parameters frontend;
113     
114     ofdm.bandwidth = bandwidth;
115     ofdm.code_rate_HP = code_rate_HP;
116     ofdm.code_rate_LP = code_rate_LP;
117     ofdm.constellation = constellation; 
118     ofdm.guard_interval = guard_interval;
119     ofdm.hierarchy_information = hierarchy_information;
120     
121     frontend.frequency = frequency;
122     frontend.inversion = inversion;
123     frontend.u.ofdm = ofdm;
124     
125     tune(frontend);
126     
127 }
128 prefix_ void senf::DVBFrontendSocketProtocol::tuneDVB_S(unsigned int frequency, 
129         fe_spectral_inversion_t inversion, 
130         unsigned int symbole_rate, /* symbol rate in Symbols per second */
131         fe_code_rate_t fec_inner) /* forward error correction (see above) */
132 {
133     struct dvb_qpsk_parameters qpsk; /* DVB-S Parameters*/
134     struct dvb_frontend_parameters frontend;
135     
136     qpsk.symbol_rate = symbole_rate;
137     qpsk.fec_inner = fec_inner;
138     
139     frontend.frequency = frequency;
140     frontend.inversion = inversion;
141     frontend.u.qpsk = qpsk;
142     
143     tune(frontend);
144 }
145
146 prefix_ void senf::DVBFrontendSocketProtocol::tuneDVB_C(unsigned int frequency, 
147         fe_spectral_inversion_t inversion,
148         unsigned int symbol_rate,
149         fe_code_rate_t fec_inner,
150         fe_modulation_t modulation)
151 {
152     struct dvb_qam_parameters qam; /* DVB-C Parameters*/
153     struct dvb_frontend_parameters frontend;
154     
155     qam.symbol_rate = symbol_rate;
156     qam.fec_inner = fec_inner;
157     qam.modulation = modulation;
158     
159     
160     frontend.frequency = frequency;
161     frontend.inversion = inversion;
162     frontend.u.qam = qam;
163        
164     tune(frontend);
165 }
166 prefix_ struct dvb_frontend_info senf::DVBFrontendSocketProtocol::getInfo()
167     const
168 {
169     struct dvb_frontend_info info;
170     if( ::ioctl(fd(), FE_GET_INFO, &info) ) {
171         SENF_THROW_SYSTEM_EXCEPTION("") << "Could not read on fildescriptor.";
172     }
173     return info;
174 }
175
176 prefix_ struct dvb_frontend_parameters senf::DVBFrontendSocketProtocol::getFrontendParam() const {
177     struct dvb_frontend_parameters frontend;
178     
179     if ( ::ioctl(fd(), FE_GET_FRONTEND, &frontend) ) 
180            SENF_THROW_SYSTEM_EXCEPTION("") << "Could not read from frontend device, read-only access to the device is sufficient.";
181     return frontend;
182 }
183
184 prefix_ void senf::DVBFrontendSocketProtocol::setFrequency(unsigned int frequency){
185
186     struct dvb_frontend_parameters frontend = getFrontendParam();
187     
188     frontend.frequency = frequency;
189     
190     tune(frontend);
191 }
192
193 prefix_ void senf::DVBFrontendSocketProtocol::setInversion(fe_spectral_inversion_t inversion){
194     
195     struct dvb_frontend_parameters frontend = getFrontendParam();
196         
197     frontend.inversion = inversion;
198         
199     tune(frontend);
200 }
201
202 prefix_ void senf::DVBFrontendSocketProtocol::setCodeRate(fe_code_rate_t fec_inner){
203     
204     fe_type_t type = getInfo().type;
205     struct dvb_frontend_parameters frontend = getFrontendParam();
206     if( type == FE_QPSK ){ /* DVB-S */
207         frontend.u.qpsk.fec_inner = fec_inner;
208     }
209     if( type == FE_QAM ){ /* DVB-C */
210         frontend.u.qam.fec_inner = fec_inner;
211     }
212     if( type == FE_OFDM ){ /* DVB-T  ATTENTION sets high and low priority code rate!*/
213         frontend.u.ofdm.code_rate_HP = fec_inner;
214         frontend.u.ofdm.code_rate_LP = fec_inner;
215     }
216     tune(frontend);
217 }
218
219 prefix_ void senf::DVBFrontendSocketProtocol::setSymbolRate(unsigned int symbol_rate){
220     
221     fe_type_t type = getInfo().type;
222     struct dvb_frontend_parameters frontend = getFrontendParam();
223     
224     if (! ( type == FE_QPSK || type == FE_QAM ) )
225         SENF_THROW_SYSTEM_EXCEPTION("Symbole rate can only be set for DVB-S or DVB-C devices.");
226     if( type == FE_QPSK ) /* DVB-S */
227         frontend.u.qpsk.symbol_rate = symbol_rate;
228     
229     if( type == FE_QAM ) /* DVB-C */
230         frontend.u.qam.symbol_rate = symbol_rate;
231     
232     tune(frontend);
233 }
234 prefix_ void senf::DVBFrontendSocketProtocol::setModulation(fe_modulation_t modulation){
235     
236     fe_type_t type = getInfo().type;
237     struct dvb_frontend_parameters frontend = getFrontendParam();
238     
239     if (! ( type == FE_OFDM || type == FE_QAM ) )
240         SENF_THROW_SYSTEM_EXCEPTION("Symbole rate can only be set for DVB-T or DVB-C devices.");
241     if( type == FE_QAM ) /* DVB-C */
242         frontend.u.qam.modulation = modulation;
243     if( type == FE_OFDM ) /* DVB-T */
244         frontend.u.ofdm.constellation = modulation;
245     
246     tune(frontend);
247 }
248
249 prefix_ void senf::DVBFrontendSocketProtocol::setBandwidth(fe_bandwidth_t bandwidth) {
250     
251     fe_type_t type = getInfo().type;
252     struct dvb_frontend_parameters frontend = getFrontendParam();
253     
254     if (type != FE_OFDM)
255         SENF_THROW_SYSTEM_EXCEPTION("") << "Bandwidth can only be set for DVB-T devices.";
256     
257     frontend.u.ofdm.bandwidth = bandwidth;
258         
259     tune(frontend);
260 }
261
262 prefix_ void senf::DVBFrontendSocketProtocol::setHighPriorityCodeRate(fe_code_rate_t code_rate_HP) {
263     
264     fe_type_t type = getInfo().type;
265     struct dvb_frontend_parameters frontend = getFrontendParam();
266     
267     if (type != FE_OFDM)
268         SENF_THROW_SYSTEM_EXCEPTION("") << "High priority bandwidth can only be set for DVB-T devices.";
269     
270     frontend.u.ofdm.code_rate_HP = code_rate_HP;
271         
272     tune(frontend);
273 }
274
275 prefix_ void senf::DVBFrontendSocketProtocol::setLowPriorityCodeRate(fe_code_rate_t code_rate_LP) {
276     
277     fe_type_t type = getInfo().type;
278     struct dvb_frontend_parameters frontend = getFrontendParam();
279     
280     if (type != FE_OFDM)
281         SENF_THROW_SYSTEM_EXCEPTION("") << "Low priority bandwidth can only be set for DVB-T devices.";
282     
283     frontend.u.ofdm.code_rate_LP = code_rate_LP;
284         
285     tune(frontend);
286 }
287
288 prefix_ void senf::DVBFrontendSocketProtocol::setGuardInterval(fe_guard_interval_t guard_interval) {
289     
290     fe_type_t type = getInfo().type;
291     struct dvb_frontend_parameters frontend = getFrontendParam();
292     
293     if (type != FE_OFDM)
294         SENF_THROW_SYSTEM_EXCEPTION("") << "Guard interval can only be set for DVB-T devices.";
295     
296     frontend.u.ofdm.guard_interval = guard_interval;
297         
298     tune(frontend);
299 }
300
301 prefix_ void senf::DVBFrontendSocketProtocol::setHierarchyInformation(fe_hierarchy_t hierarchy_information) {
302     
303     fe_type_t type = getInfo().type;
304     struct dvb_frontend_parameters frontend = getFrontendParam();
305     
306     if (type != FE_OFDM)
307         SENF_THROW_SYSTEM_EXCEPTION("") << "Hierachy information can only be set for DVB-T devices.";
308     
309     frontend.u.ofdm.hierarchy_information = hierarchy_information;
310         
311     tune(frontend);
312 }
313
314 prefix_ int16_t senf::DVBFrontendSocketProtocol::signalStrength()
315     const
316 {
317     int16_t strength;
318     if (::ioctl(fd(), FE_READ_SIGNAL_STRENGTH, &strength) < 0)
319         SENF_THROW_SYSTEM_EXCEPTION("Could not get signal strength of DVB adapter.");
320     return strength;
321 }
322
323 prefix_ int16_t senf::DVBFrontendSocketProtocol::signalNoiseRatio()
324     const
325 {
326     int16_t snr;
327     if (::ioctl(fd(), FE_READ_SNR, &snr) < 0)
328         SENF_THROW_SYSTEM_EXCEPTION("Could not get signal-to-noise ratio of DVB adapter.");
329     return snr;
330 }
331
332 prefix_ uint32_t senf::DVBFrontendSocketProtocol::bitErrorRate()
333     const
334 {
335     uint32_t ber;
336     if (::ioctl(fd(), FE_READ_BER, &ber) < 0)
337         SENF_THROW_SYSTEM_EXCEPTION("Could not get bit error rate of DVB adapter.");
338     return ber;
339 }
340
341 ///////////////////////////////cc.e////////////////////////////////////////
342 #undef prefix_
343 //#include "DVBFrontendHandle.mpp"
344
345
346 // Local Variables:
347 // mode: c++
348 // fill-column: 100
349 // c-file-style: "senf"
350 // indent-tabs-mode: nil
351 // ispell-local-dictionary: "american"
352 // compile-command: "scons -u test"
353 // comment-column: 40
354 // End: