@@ -250,7 +250,8 @@ cDiseqc::eDiseqcActions cDiseqc::Execute
case 'V': return daVoltage18;
case 'A': return daMiniA;
case 'B': return daMiniB;
- case 'G': return daGotoX;
+ case 'G': return daGotoX;
+ case 'g': return daGotoX_Virtual;
case 'W': *CurrentAction = Wait(*CurrentAction); break;
case 'S': *CurrentAction = GetScrBank(*CurrentAction); break;
case '[': *CurrentAction = GetCodes(*CurrentAction, Codes, MaxCodes);
@@ -276,6 +277,7 @@ cDiseqc::eDiseqcActions cDiseqc::TestFor
switch (*(*CurrentAction)++) {
case ' ': break;
case 'G': return daGotoX;
+ case 'g': return daGotoX_Virtual;
default: return daNone;
}
}
@@ -50,7 +50,8 @@ public:
daVoltage18,
daMiniA,
daMiniB,
- daGotoX,
+ daGotoX,
+ daGotoX_Virtual,
daScr,
daCodes,
};
@@ -460,6 +460,56 @@ bool cDvbTuner::IsTunedTo(const cChannel
return strcmp(channel.Parameters(), Channel->Parameters()) == 0;
}
+void HandleGotox_Virtual(int fd_frontend, int new_source)
+{
+ int gotoXTable[10] = { 0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E };
+ int satlong;
+
+ if (Setup.UseGotox == 0)
+ return;
+
+ // Check if zapped into new source position?
+ if ((new_source & 0xFF000000) != 0x53000000)
+ return; // Fail, not S type source
+ satlong = (new_source & 0x00000FFFF);
+ if (new_source & 0x00008000) {
+ satlong ^= 0x0000FFFF; satlong++; satlong *= (-1);
+ }
+ int Long=Setup.GotoxEW ? -Setup.GotoxLong : Setup.GotoxLong;
+ int Lat=Setup.GotoxSN ? -Setup.GotoxLat : Setup.GotoxLat;
+ double azimuth=M_PI+atan(tan((satlong-Long)*M_PI/1800)/sin(Lat*M_PI/1800));
+ double x=acos(cos((satlong-Long)*M_PI/1800)*cos(Lat*M_PI/1800));
+ double elevation=atan((cos(x)-0.1513)/sin(x));
+ double SatHourangle=180+atan((-cos(elevation)*sin(azimuth))/(sin(elevation)*cos(Lat*M_PI/1800)
+ -cos(elevation)*sin(Lat*M_PI/1800)*cos(azimuth)))*180/M_PI;
+ int tmp=(int)(fabs(180-SatHourangle)*10);
+ tmp=(tmp/10)*0x10 + gotoXTable[ tmp % 10 ];
+ int p2=(tmp%0x0100);
+ int p1=(tmp/0x0100);
+ if (SatHourangle < 180)
+ p1 |= 0xe0;
+ else
+ p1 |= 0xd0;
+
+ // Send 1st GotoX command, then wait > 15ms
+ uchar gotox_bytes[5] = { 0xe0, 0x31, 0x6e, p1, p2};
+ struct dvb_diseqc_master_cmd gotox_cmd;
+ memcpy(gotox_cmd.msg, gotox_bytes, 5);
+ gotox_cmd.msg_len = 5;
+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd));
+ cCondWait::SleepMs(20);
+
+ // Send repeated GotoX command, then wait > 15ms
+ if (Setup.GotoxRepeat) {
+ gotox_bytes[0] = 0xe1;
+ memcpy(gotox_cmd.msg, gotox_bytes, 5);
+ CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &gotox_cmd));
+ cCondWait::SleepMs(20);
+ }
+
+ dsyslog("DiSEqC GotoX_Virtual done.");
+}
+
void HandleGotox(int fd_frontend, int new_source)
{
@@ -738,15 +779,16 @@ void cDvbTuner::ExecuteDiseqc(const cDis
if (da == cDiseqc::daNone)
break;
switch (da) {
- case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
- case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
- case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
- case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
- case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
- case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
- case cDiseqc::daGotoX: HandleGotox(fd_frontend, channel.Source()); break;
- case cDiseqc::daCodes: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break;
- default: esyslog("ERROR: unknown diseqc command %d", da);
+ case cDiseqc::daToneOff: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_OFF)); break;
+ case cDiseqc::daToneOn: CHECK(ioctl(fd_frontend, FE_SET_TONE, SEC_TONE_ON)); break;
+ case cDiseqc::daVoltage13: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_13)); break;
+ case cDiseqc::daVoltage18: CHECK(ioctl(fd_frontend, FE_SET_VOLTAGE, SEC_VOLTAGE_18)); break;
+ case cDiseqc::daMiniA: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_A)); break;
+ case cDiseqc::daMiniB: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_BURST, SEC_MINI_B)); break;
+ case cDiseqc::daGotoX: HandleGotox(fd_frontend, channel.Source()); break;
+ case cDiseqc::daGotoX_Virtual: HandleGotox_Virtual(fd_frontend, channel.Source()); break;
+ case cDiseqc::daCodes: CHECK(ioctl(fd_frontend, FE_DISEQC_SEND_MASTER_CMD, &cmd)); break;
+ default: esyslog("ERROR: unknown diseqc command %d", da);
}
}
if (scr)
@@ -762,7 +804,7 @@ bool cDvbTuner::TestDiseqcForGotoXX(cons
cDiseqc::eDiseqcActions da = Diseqc->TestForGotoXX(&CurrentAction);
if (da == cDiseqc::daNone)
break;
- if (da == cDiseqc::daGotoX)
+ if((da == cDiseqc::daGotoX) || (da == cDiseqc::daGotoX_Virtual))
return true;
}
return false;