aaf459fbcc1920e8690ca0e5bde501c4103cc816
[enigma2.git] / lib / dvb / sec.cpp
1 #include <config.h>
2 #include <lib/dvb/sec.h>
3 #include <lib/dvb/rotor_calc.h>
4
5 #if HAVE_DVB_API_VERSION < 3
6 #define INVERSION Inversion
7 #define FREQUENCY Frequency
8 #define FEC_INNER FEC_inner
9 #define SYMBOLRATE SymbolRate
10 #else
11 #define INVERSION inversion
12 #define FREQUENCY frequency
13 #define FEC_INNER fec_inner
14 #define SYMBOLRATE symbol_rate
15 #endif
16 #include <lib/base/eerror.h>
17
18 DEFINE_REF(eDVBSatelliteEquipmentControl);
19
20 eDVBSatelliteEquipmentControl *eDVBSatelliteEquipmentControl::instance;
21
22 eDVBSatelliteEquipmentControl::eDVBSatelliteEquipmentControl()
23         :m_lnbidx(-1), m_curSat(m_lnbs[0].m_satellites.end())
24 {
25         if (!instance)
26                 instance = this;
27
28         clear();
29
30 // ASTRA
31         addLNB();
32         setLNBTunerMask(1);
33         setLNBLOFL(9750000);
34         setLNBThreshold(11750000);
35         setLNBLOFH(10600000);
36         setDiSEqCMode(eDVBSatelliteDiseqcParameters::V1_0);
37         setToneburst(eDVBSatelliteDiseqcParameters::NO);
38         setRepeats(0);
39         setCommittedCommand(eDVBSatelliteDiseqcParameters::AA);
40         setCommandOrder(0); // committed, toneburst
41         setFastDiSEqC(false);
42         setSeqRepeat(false);
43         addSatellite(192);
44         setVoltageMode(eDVBSatelliteSwitchParameters::HV);
45         setToneMode(eDVBSatelliteSwitchParameters::HILO);
46
47 // HOTBIRD
48         addLNB();
49         setLNBTunerMask(1);
50         setLNBLOFL(9750000);
51         setLNBLOFH(10600000);
52         setLNBThreshold(11750000);
53         setDiSEqCMode(eDVBSatelliteDiseqcParameters::V1_0);
54         setToneburst(eDVBSatelliteDiseqcParameters::NO);
55         setRepeats(0);
56         setCommittedCommand(eDVBSatelliteDiseqcParameters::AB);
57         setCommandOrder(0); // committed, toneburst
58         setFastDiSEqC(false);
59         setSeqRepeat(false);
60         addSatellite(130);
61         setVoltageMode(eDVBSatelliteSwitchParameters::HV);
62         setToneMode(eDVBSatelliteSwitchParameters::HILO);
63 }
64
65 int eDVBSatelliteEquipmentControl::canTune(const eDVBFrontendParametersSatellite &sat, iDVBFrontend *fe, int frontend_id )
66 {
67         int ret=0;
68
69         for (int idx=0; idx <= m_lnbidx; ++idx )
70         {
71                 eDVBSatelliteLNBParameters &lnb_param = m_lnbs[idx];
72                 if ( lnb_param.tuner_mask & frontend_id ) // lnb for correct tuner?
73                 {
74                         eDVBSatelliteDiseqcParameters &di_param = lnb_param.m_diseqc_parameters;
75                         eDVBSatelliteRotorParameters &rotor_param = lnb_param.m_rotor_parameters;
76
77                         std::map<int, eDVBSatelliteSwitchParameters>::iterator sit =
78                                 lnb_param.m_satellites.find(sat.orbital_position);
79                         if ( sit != lnb_param.m_satellites.end())
80                         {
81                                 int curRotorPos = -1;
82                                 fe->getData(6, curRotorPos);
83
84                                 if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 )  // ROTOR
85                                 {
86                                         if ( curRotorPos == sat.orbital_position )
87                                                 ret=20;
88                                         else
89                                                 ret=10;
90                                 }
91                                 else if (!ret)
92                                         ret=40;
93                         }
94                 }
95         }
96         return ret;
97 }
98
99 RESULT eDVBSatelliteEquipmentControl::prepare(iDVBFrontend &frontend, FRONTENDPARAMETERS &parm, eDVBFrontendParametersSatellite &sat)
100 {
101         for (int idx=0; idx <= m_lnbidx; ++idx )
102         {
103                 eDVBSatelliteLNBParameters &lnb_param = m_lnbs[idx];
104                 eDVBSatelliteDiseqcParameters &di_param = lnb_param.m_diseqc_parameters;
105                 eDVBSatelliteRotorParameters &rotor_param = lnb_param.m_rotor_parameters;
106
107                 std::map<int, eDVBSatelliteSwitchParameters>::iterator sit =
108                         lnb_param.m_satellites.find(sat.orbital_position);
109                 if ( sit != lnb_param.m_satellites.end())
110                 {
111                         eDVBSatelliteSwitchParameters &sw_param = sit->second;
112
113                         int hi=0,
114                                 voltage = iDVBFrontend::voltageOff,
115                                 tone = iDVBFrontend::toneOff,
116                                 csw = di_param.m_committed_cmd,
117                                 ucsw = di_param.m_uncommitted_cmd,
118                                 toneburst = di_param.m_toneburst_param,
119                                 lastcsw = -1,
120                                 lastucsw = -1,
121                                 lastToneburst = -1,
122                                 lastRotorCmd = -1,
123                                 curRotorPos = -1;
124
125                         frontend.getData(0, lastcsw);
126                         frontend.getData(1, lastucsw);
127                         frontend.getData(2, lastToneburst);
128                         frontend.getData(5, lastRotorCmd);
129                         frontend.getData(6, curRotorPos);
130
131                         if ( sat.frequency > lnb_param.m_lof_threshold )
132                                 hi = 1;
133
134                         if (hi)
135                                 parm.FREQUENCY = sat.frequency - lnb_param.m_lof_hi;
136                         else
137                                 parm.FREQUENCY = sat.frequency - lnb_param.m_lof_lo;
138
139                         parm.INVERSION = (!sat.inversion) ? INVERSION_ON : INVERSION_OFF;
140
141                         switch (sat.fec)
142                         {
143                                 default:
144                                 case eDVBFrontendParametersSatellite::FEC::fNone:
145                                         eDebug("no fec set.. assume auto");
146                                 case eDVBFrontendParametersSatellite::FEC::fAuto:
147                                         parm.u.qpsk.FEC_INNER = FEC_AUTO;
148                                         break;
149                                 case eDVBFrontendParametersSatellite::FEC::f1_2:
150                                         parm.u.qpsk.FEC_INNER = FEC_1_2;
151                                         break;
152                                 case eDVBFrontendParametersSatellite::FEC::f2_3:
153                                         parm.u.qpsk.FEC_INNER = FEC_2_3;
154                                         break;
155                                 case eDVBFrontendParametersSatellite::FEC::f3_4:
156                                         parm.u.qpsk.FEC_INNER = FEC_3_4;
157                                         break;
158                                 case eDVBFrontendParametersSatellite::FEC::f5_6:
159                                         parm.u.qpsk.FEC_INNER = FEC_5_6;
160                                         break;
161                                 case eDVBFrontendParametersSatellite::FEC::f7_8: 
162                                         parm.u.qpsk.FEC_INNER = FEC_7_8;
163                                         break;
164                         }
165
166                         parm.u.qpsk.SYMBOLRATE = sat.symbol_rate;
167
168                         if ( sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::_14V
169                                 || ( sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Vertical
170                                         && sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::HV )  )
171                                 voltage = iDVBFrontend::voltage13;
172                         else if ( sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::_18V
173                                 || ( sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal
174                                         && sw_param.m_voltage_mode == eDVBSatelliteSwitchParameters::HV )  )
175                                 voltage = iDVBFrontend::voltage18;
176
177                         if ( (sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::ON)
178                                 || ( sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::HILO && hi ) )
179                                 tone = iDVBFrontend::toneOn;
180                         else if ( (sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::OFF)
181                                 || ( sw_param.m_22khz_signal == eDVBSatelliteSwitchParameters::HILO && !hi ) )
182                                 tone = iDVBFrontend::toneOff;
183
184                         eSecCommandList sec_sequence;
185
186                         if (di_param.m_diseqc_mode >= eDVBSatelliteDiseqcParameters::V1_0)
187                         {
188                                 if ( di_param.m_committed_cmd < eDVBSatelliteDiseqcParameters::SENDNO )
189                                 {
190                                         csw = 0xF0 | (csw << 2);
191                                         if (hi)
192                                                 csw |= 1;
193                                         if (sat.polarisation == eDVBFrontendParametersSatellite::Polarisation::Horizontal)
194                                                 csw |= 2;
195                                 }
196
197                                 bool send_csw =
198                                         (di_param.m_committed_cmd != eDVBSatelliteDiseqcParameters::SENDNO);
199                                 bool changed_csw = send_csw && csw != lastcsw;
200
201                                 bool send_ucsw =
202                                         (di_param.m_uncommitted_cmd && di_param.m_diseqc_mode > eDVBSatelliteDiseqcParameters::V1_0);
203                                 bool changed_ucsw = send_ucsw && ucsw != lastucsw;
204
205                                 bool send_burst =
206                                         (di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO);
207                                 bool changed_burst = send_burst && toneburst != lastToneburst;
208
209                                 bool send_diseqc = changed_ucsw;
210                                 if (!send_diseqc)
211                                         send_diseqc = changed_burst && (send_ucsw || send_csw);
212                                 if (!send_diseqc)
213                                 {
214                                         send_diseqc = changed_csw;
215                                         if ( send_diseqc && di_param.m_use_fast && (csw & 0xF0) && (lastcsw & 0xF0) && ((csw / 4) == (lastcsw / 4)) )
216                                                 send_diseqc = false;
217                                 }
218
219                                 if ( send_diseqc || changed_burst )
220                                 {
221                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
222                                         eSecCommand::pair compare;
223                                         compare.voltage = voltage;
224                                         compare.steps = +3;
225                                         sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // voltage already correct ?
226                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
227                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );
228                                 }
229
230                                 for (int seq_repeat = 0; seq_repeat < (di_param.m_seq_repeat?2:1); ++seq_repeat)
231                                 {
232                                         if ( di_param.m_command_order & 1 && // toneburst at begin of sequence
233                                                 changed_burst && di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO )
234                                         {
235                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SEND_TONEBURST, di_param.m_toneburst_param) );
236                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );
237                                                 frontend.setData(2, di_param.m_toneburst_param);
238                                         }
239
240                                         if ( send_diseqc )
241                                         {
242                                                 int loops=0;
243
244                                                 if ( send_csw )
245                                                         ++loops;
246                                                 if ( send_ucsw )
247                                                         ++loops;
248
249                                                 for ( int i=0; i < di_param.m_repeats; ++i )
250                                                         loops *= 2;
251
252                                                 for ( int i = 0; i < loops;)  // fill commands...
253                                                 {
254                                                         eDVBDiseqcCommand diseqc;
255                                                         diseqc.len = 4;
256                                                         diseqc.data[0] = i ? 0xE1 : 0xE0;
257                                                         diseqc.data[1] = 0x10;
258
259                                                         if ( !send_csw || (send_ucsw && (di_param.m_command_order & 4) ) )
260                                                         {
261                                                                 diseqc.data[2] = 0x39;
262                                                                 diseqc.data[3] = ucsw;
263                                                         }
264                                                         else
265                                                         {
266                                                                 diseqc.data[2] = 0x38;
267                                                                 diseqc.data[3] = csw;
268                                                         }
269                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
270
271                                                         i++;
272                                                         if ( i < loops )
273                                                         {
274                                                                 int cmd=0;
275                                                                 if (diseqc.data[2] == 0x38 && send_ucsw)
276                                                                         cmd=0x39;
277                                                                 else if (diseqc.data[2] == 0x39 && send_csw)
278                                                                         cmd=0x38;
279                                                                 if (cmd)
280                                                                 {
281                                                                         static int delay = (120 - 54) / 2;  // standard says 100msek between two repeated commands
282                                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, delay) );
283                                                                         diseqc.data[2]=cmd;
284                                                                         diseqc.data[3]=(cmd==0x38) ? csw : ucsw;
285                                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
286                                                                         ++i;
287                                                                         if ( i < loops )
288                                                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, delay ) );
289                                                                         else
290                                                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );
291                                                                 }
292                                                                 else  // delay 120msek when no command is in repeat gap
293                                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 120) );
294                                                         }
295                                                         else
296                                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );
297
298                                                         frontend.setData(0, csw);
299                                                         frontend.setData(1, ucsw);
300                                                 }
301                                         }
302
303                                         if ( !(di_param.m_command_order & 1) && // toneburst at end of sequence
304                                                 (changed_burst || send_diseqc) && di_param.m_toneburst_param != eDVBSatelliteDiseqcParameters::NO )
305                                         {
306                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SEND_TONEBURST, di_param.m_toneburst_param) );
307                                                 sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );
308                                                 frontend.setData(2, di_param.m_toneburst_param);
309                                         }
310                                 }
311
312                                 if ( di_param.m_diseqc_mode == eDVBSatelliteDiseqcParameters::V1_2 )
313                                 {
314                                         int RotorCmd=0;
315                                         bool useGotoXX = false;
316
317                                         if (sw_param.m_rotorPosNum) // we have stored rotor pos?
318                                                 RotorCmd=sw_param.m_rotorPosNum;
319                                         else  // we must calc gotoxx cmd
320                                         {
321                                                 eDebug("Entry for %d,%d° not in Rotor Table found... i try gotoXX°", sat.orbital_position / 10, sat.orbital_position % 10 );
322                                                 useGotoXX = true;
323
324                                                 int satDir = sat.orbital_position < 0 ?
325                                                         eDVBSatelliteRotorParameters::WEST :
326                                                         eDVBSatelliteRotorParameters::EAST;
327
328                                                 double  SatLon = abs(sat.orbital_position)/10.00,
329                                                                 SiteLat = rotor_param.m_gotoxx_parameters.m_latitude,
330                                                                 SiteLon = rotor_param.m_gotoxx_parameters.m_longitude;
331
332                                                 if ( rotor_param.m_gotoxx_parameters.m_la_direction == eDVBSatelliteRotorParameters::SOUTH )
333                                                         SiteLat = -SiteLat;
334
335                                                 if ( rotor_param.m_gotoxx_parameters.m_lo_direction == eDVBSatelliteRotorParameters::WEST )
336                                                         SiteLon = 360 - SiteLon;
337
338                                                 if (satDir == eDVBSatelliteRotorParameters::WEST )
339                                                         SatLon = 360 - SatLon;
340
341                                                 eDebug("siteLatitude = %lf, siteLongitude = %lf, %lf degrees", SiteLat, SiteLon, SatLon );
342                                                 double satHourAngle =
343                                                         calcSatHourangle( SatLon, SiteLat, SiteLon );
344                                                 eDebug("PolarmountHourAngle=%lf", satHourAngle );
345
346                                                 static int gotoXTable[10] =
347                                                         { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
348
349                                                 if (SiteLat >= 0) // Northern Hemisphere
350                                                 {
351                                                         int tmp=(int)round( fabs( 180 - satHourAngle ) * 10.0 );
352                                                         RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
353
354                                                         if (satHourAngle < 180) // the east
355                                                                 RotorCmd |= 0xE000;
356                                                         else                                    // west
357                                                                 RotorCmd |= 0xD000;
358                                                 }
359                                                 else // Southern Hemisphere
360                                                 {
361                                                         if (satHourAngle < 180) // the east
362                                                         {
363                                                                 int tmp=(int)round( fabs( satHourAngle ) * 10.0 );
364                                                                 RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
365                                                                 RotorCmd |= 0xD000;
366                                                         }
367                                                         else                                    // west
368                                                         {          
369                                                                 int tmp=(int)round( fabs( 360 - satHourAngle ) * 10.0 );
370                                                                 RotorCmd = (tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
371                                                                 RotorCmd |= 0xE000;
372                                                         }
373                                                 }
374                                                 eDebug("RotorCmd = %04x", RotorCmd);
375                                         }
376                                         if ( RotorCmd != lastRotorCmd )
377                                         {
378                                                 if ( changed_burst || send_diseqc )
379                                                 {
380                                                         // override first voltage change
381                                                         *(++(++sec_sequence.begin()))=eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13);
382                                                         // wait 1 second after first switch diseqc command
383                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 1000) );
384                                                 }
385                                                 else  // no other diseqc commands before
386                                                 {
387                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, iDVBFrontend::toneOff) );
388                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 15) );  // wait 15msec after tone change
389                                                         eSecCommand::pair compare;
390                                                         compare.voltage = voltage;
391                                                         compare.steps = +3;
392                                                         sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // voltage already correct ?
393                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) );
394                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // wait 50msec after voltage change
395                                                 }
396
397                                                 eDVBDiseqcCommand diseqc;
398                                                 diseqc.data[0] = 0xE0;
399                                                 diseqc.data[1] = 0x31;          // positioner
400                                                 if ( useGotoXX )
401                                                 {
402                                                         diseqc.len = 5;
403                                                         diseqc.data[2] = 0x6E;  // drive to angular position
404                                                         diseqc.data[3] = ((RotorCmd & 0xFF00) / 0x100);
405                                                         diseqc.data[4] = RotorCmd & 0xFF;
406                                                 }
407                                                 else
408                                                 {
409                                                         diseqc.len = 4;
410                                                         diseqc.data[2] = 0x6B;  // goto stored sat position
411                                                         diseqc.data[3] = RotorCmd;
412                                                 }
413
414                                                 if ( rotor_param.m_inputpower_parameters.m_use )
415                                                 { // use measure rotor input power to detect rotor state
416                                                         eSecCommand::rotor cmd;
417 // measure idle power values
418                                                         sec_sequence.push_back( eSecCommand(eSecCommand::IF_IDLE_INPUTPOWER_AVAIL_GOTO, +8) ); // already measured?
419                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // wait 50msec after voltage change
420                                                         sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 0) );
421                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18) );
422                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 100) );  // wait 100msec before measure
423                                                         sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_IDLE_INPUTPOWER, 1) );
424                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage13) ); // back to lower voltage
425                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // wait 50msec
426 ////////////////////////////
427                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeStatic) );
428                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // wait 50msec after voltage change
429                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SEND_DISEQC, diseqc) );
430                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, 40) );  // 2 seconds rotor start timout
431 // rotor start loop
432                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // 50msec delay
433                                                         sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
434                                                         cmd.direction=1;  // check for running rotor
435                                                         cmd.deltaA=rotor_param.m_inputpower_parameters.m_delta;
436                                                         cmd.steps=+3;
437                                                         cmd.okcount=0;
438                                                         sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) );  // check if rotor has started
439                                                         sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +10 ) );  // timeout .. we assume now the rotor is already at the correct position
440                                                         sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );  // goto loop start
441 ////////////////////
442                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_TIMEOUT, 2400) );  // 2 minutes running timeout
443                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, iDVBFrontend::voltage18) );
444                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_POWER_LIMITING_MODE, eSecCommand::modeDynamic) );
445 // rotor running loop
446                                                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 50) );  // wait 50msec
447                                                         sec_sequence.push_back( eSecCommand(eSecCommand::MEASURE_RUNNING_INPUTPOWER) );
448                                                         cmd.direction=0;  // check for stopped rotor
449                                                         cmd.steps=+3;
450                                                         sec_sequence.push_back( eSecCommand(eSecCommand::IF_INPUTPOWER_DELTA_GOTO, cmd ) );
451                                                         sec_sequence.push_back( eSecCommand(eSecCommand::IF_TIMEOUT_GOTO, +3 ) );  // timeout ? this should never happen
452                                                         sec_sequence.push_back( eSecCommand(eSecCommand::GOTO, -4) );  // running loop start
453 /////////////////////
454                                                         sec_sequence.push_back( eSecCommand(eSecCommand::UPDATE_CURRENT_ROTORPARAMS) );
455                                                         frontend.setData(3, RotorCmd);
456                                                         frontend.setData(4, sat.orbital_position);
457                                                 }
458                                                 else
459                                                         eFatal("rotor turning without inputpowermeasure not implemented yet");
460                                         }
461                                 }
462                         }
463
464                         eSecCommand::pair compare;
465                         compare.voltage = voltage;
466                         compare.steps = +3;
467                         sec_sequence.push_back( eSecCommand(eSecCommand::IF_VOLTAGE_GOTO, compare) ); // voltage already correct ?
468                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_VOLTAGE, voltage) );
469                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 10) );
470
471                         sec_sequence.push_back( eSecCommand(eSecCommand::SET_TONE, tone) );
472                         sec_sequence.push_back( eSecCommand(eSecCommand::SLEEP, 15) );
473
474                         frontend.setSecSequence(sec_sequence);
475
476                         return 0;
477                 }
478         }
479
480         eDebug("found no satellite configuration for orbital position (%d)", sat.orbital_position );
481
482         return -1;
483 }
484
485 RESULT eDVBSatelliteEquipmentControl::clear()
486 {
487         for (int i=0; i < m_lnbidx; ++i)
488         {
489                 m_lnbs[i].m_satellites.clear();
490                 m_lnbs[i].tuner_mask = 0;
491         }
492         m_lnbidx=-1;
493         return 0;
494 }
495
496 /* LNB Specific Parameters */
497 RESULT eDVBSatelliteEquipmentControl::addLNB()
498 {
499         if ( m_lnbidx < (int)(sizeof(m_lnbs) / sizeof(eDVBSatelliteLNBParameters)))
500                 m_curSat=m_lnbs[++m_lnbidx].m_satellites.end();
501         else
502         {
503                 eDebug("no more LNB free... cnt is %d", m_lnbidx);
504                 return -ENOSPC;
505         }
506         return 0;
507 }
508
509 RESULT eDVBSatelliteEquipmentControl::setLNBTunerMask(int tunermask)
510 {
511         if ( currentLNBValid() )
512                 m_lnbs[m_lnbidx].tuner_mask = tunermask;
513         else
514                 return -ENOENT;
515         return 0;
516 }
517
518 RESULT eDVBSatelliteEquipmentControl::setLNBLOFL(int lofl)
519 {
520         if ( currentLNBValid() )
521                 m_lnbs[m_lnbidx].m_lof_lo = lofl;
522         else
523                 return -ENOENT;
524         return 0;
525 }
526
527 RESULT eDVBSatelliteEquipmentControl::setLNBLOFH(int lofh)
528 {
529         if ( currentLNBValid() )
530                 m_lnbs[m_lnbidx].m_lof_hi = lofh;
531         else
532                 return -ENOENT;
533         return 0;
534 }
535
536 RESULT eDVBSatelliteEquipmentControl::setLNBThreshold(int threshold)
537 {
538         if ( currentLNBValid() )
539                 m_lnbs[m_lnbidx].m_lof_threshold = threshold;
540         else
541                 return -ENOENT;
542         return 0;
543 }
544
545 RESULT eDVBSatelliteEquipmentControl::setLNBIncreasedVoltage(bool onoff)
546 {
547         if ( currentLNBValid() )
548                 m_lnbs[m_lnbidx].m_increased_voltage = onoff;
549         else
550                 return -ENOENT;
551         return 0;
552 }
553
554 /* DiSEqC Specific Parameters */
555 RESULT eDVBSatelliteEquipmentControl::setDiSEqCMode(int diseqcmode)
556 {
557         if ( currentLNBValid() )
558                 m_lnbs[m_lnbidx].m_diseqc_parameters.m_diseqc_mode = (eDVBSatelliteDiseqcParameters::t_diseqc_mode)diseqcmode;
559         else
560                 return -ENOENT;
561         return 0;
562 }
563
564 RESULT eDVBSatelliteEquipmentControl::setToneburst(int toneburst)
565 {
566         if ( currentLNBValid() )
567                 m_lnbs[m_lnbidx].m_diseqc_parameters.m_toneburst_param = (eDVBSatelliteDiseqcParameters::t_toneburst_param)toneburst;
568         else
569                 return -ENOENT;
570         return 0;
571 }
572
573 RESULT eDVBSatelliteEquipmentControl::setRepeats(int repeats)
574 {
575         if ( currentLNBValid() )
576                 m_lnbs[m_lnbidx].m_diseqc_parameters.m_repeats=repeats;
577         else
578                 return -ENOENT;
579         return 0;
580 }
581
582 RESULT eDVBSatelliteEquipmentControl::setCommittedCommand(int command)
583 {
584         if ( currentLNBValid() )
585                 m_lnbs[m_lnbidx].m_diseqc_parameters.m_committed_cmd=command;
586         else
587                 return -ENOENT;
588         return 0;
589 }
590
591 RESULT eDVBSatelliteEquipmentControl::setUncommittedCommand(int command)
592 {
593         if ( currentLNBValid() )
594                 m_lnbs[m_lnbidx].m_diseqc_parameters.m_uncommitted_cmd = command;
595         else
596                 return -ENOENT;
597         return 0;
598 }
599
600 RESULT eDVBSatelliteEquipmentControl::setCommandOrder(int order)
601 {
602         if ( currentLNBValid() )
603                 m_lnbs[m_lnbidx].m_diseqc_parameters.m_command_order=order;
604         else
605                 return -ENOENT;
606         return 0;
607 }
608
609 RESULT eDVBSatelliteEquipmentControl::setFastDiSEqC(bool onoff)
610 {
611         if ( currentLNBValid() )
612                 m_lnbs[m_lnbidx].m_diseqc_parameters.m_use_fast=onoff;
613         else
614                 return -ENOENT;
615         return 0;
616 }
617
618 RESULT eDVBSatelliteEquipmentControl::setSeqRepeat(bool onoff)
619 {
620         if ( currentLNBValid() )
621                 m_lnbs[m_lnbidx].m_diseqc_parameters.m_seq_repeat = onoff;
622         else
623                 return -ENOENT;
624         return 0;
625 }
626
627 /* Rotor Specific Parameters */
628 RESULT eDVBSatelliteEquipmentControl::setLongitude(float longitude)
629 {
630         if ( currentLNBValid() )
631                 m_lnbs[m_lnbidx].m_rotor_parameters.m_gotoxx_parameters.m_longitude=longitude;
632         else
633                 return -ENOENT;
634         return 0;
635 }
636
637 RESULT eDVBSatelliteEquipmentControl::setLatitude(float latitude)
638 {
639         if ( currentLNBValid() )
640                 m_lnbs[m_lnbidx].m_rotor_parameters.m_gotoxx_parameters.m_latitude=latitude;
641         else
642                 return -ENOENT;
643         return 0;
644 }
645
646 RESULT eDVBSatelliteEquipmentControl::setLoDirection(int direction)
647 {
648         if ( currentLNBValid() )
649                 m_lnbs[m_lnbidx].m_rotor_parameters.m_gotoxx_parameters.m_lo_direction=direction;
650         else
651                 return -ENOENT;
652         return 0;
653 }
654
655 RESULT eDVBSatelliteEquipmentControl::setLaDirection(int direction)
656 {
657         if ( currentLNBValid() )
658                 m_lnbs[m_lnbidx].m_rotor_parameters.m_gotoxx_parameters.m_la_direction=direction;
659         else
660                 return -ENOENT;
661         return 0;
662 }
663
664 RESULT eDVBSatelliteEquipmentControl::setUseInputpower(bool onoff)
665 {
666         if ( currentLNBValid() )
667                 m_lnbs[m_lnbidx].m_rotor_parameters.m_inputpower_parameters.m_use=onoff;
668         else
669                 return -ENOENT;
670         return 0;
671 }
672
673 RESULT eDVBSatelliteEquipmentControl::setInputpowerDelta(int delta)
674 {
675         if ( currentLNBValid() )
676                 m_lnbs[m_lnbidx].m_rotor_parameters.m_inputpower_parameters.m_delta=delta;
677         else
678                 return -ENOENT;
679         return 0;
680 }
681
682 /* Satellite Specific Parameters */
683 RESULT eDVBSatelliteEquipmentControl::addSatellite(int orbital_position)
684 {
685         if ( currentLNBValid() )
686         {
687                 std::map<int, eDVBSatelliteSwitchParameters>::iterator it =
688                         m_lnbs[m_lnbidx].m_satellites.find(orbital_position);
689                 if ( it == m_lnbs[m_lnbidx].m_satellites.end() )
690                 {
691                         std::pair<std::map<int, eDVBSatelliteSwitchParameters>::iterator, bool > ret =
692                                 m_lnbs[m_lnbidx].m_satellites.insert(
693                                         std::pair<int, eDVBSatelliteSwitchParameters>(orbital_position, eDVBSatelliteSwitchParameters())
694                                 );
695                         if ( ret.second )
696                                 m_curSat = ret.first;
697                         else
698                                 return -ENOMEM;
699                 }
700                 else
701                         return -EEXIST;
702         }
703         else
704                 return -ENOENT;
705         return 0;
706 }
707
708 RESULT eDVBSatelliteEquipmentControl::setVoltageMode(int mode)
709 {
710         if ( currentLNBValid() && m_curSat != m_lnbs[m_lnbidx].m_satellites.end() )
711                 m_curSat->second.m_voltage_mode = (eDVBSatelliteSwitchParameters::t_voltage_mode)mode;
712         else
713                 return -ENOENT;
714         return 0;
715
716 }
717
718 RESULT eDVBSatelliteEquipmentControl::setToneMode(int mode)
719 {
720         if ( currentLNBValid() )
721         {
722                 if ( m_curSat != m_lnbs[m_lnbidx].m_satellites.end() )
723                         m_curSat->second.m_22khz_signal = (eDVBSatelliteSwitchParameters::t_22khz_signal)mode;
724                 else
725                         return -EPERM;
726         }
727         else
728                 return -ENOENT;
729         return 0;
730 }
731
732 RESULT eDVBSatelliteEquipmentControl::setRotorPosNum(int rotor_pos_num)
733 {
734         if ( currentLNBValid() )
735         {
736                 if ( m_curSat != m_lnbs[m_lnbidx].m_satellites.end() )
737                         m_curSat->second.m_rotorPosNum=rotor_pos_num;
738                 else
739                         return -EPERM;
740         }
741         else
742                 return -ENOENT;
743         return 0;
744 }