From fc926f81da5ac3d0a310a7fc8c960aee2b04c9bb Mon Sep 17 00:00:00 2001 From: Jochen Dolze Date: Sat, 3 Jan 2009 18:57:48 +0100 Subject: Changed wakeup (now set automatically) Changed setup Changed device chooser Bugfixed segfault with obsolete channels --- filter.cpp | 214 ++++++++++++++++++++++---------------------- global.cpp | 273 +++++++++++++++++++++++++++++++++++---------------------- global.h | 141 +++++++++++++++-------------- infosatepg.cpp | 149 ++++++++++++++++++++++--------- po/de_DE.po | 8 +- process.cpp | 20 +++-- process.h | 2 +- setup.cpp | 33 ++++--- status.cpp | 9 +- 9 files changed, 498 insertions(+), 351 deletions(-) diff --git a/filter.cpp b/filter.cpp index 7a3bc89..2eacea6 100644 --- a/filter.cpp +++ b/filter.cpp @@ -15,61 +15,60 @@ cFilterInfosatepg::cFilterInfosatepg(cGlobalInfosatepg *Global) { - global = Global; - Set(global->Pid,0,0); + global = Global; + Set(global->Pid,0,0); } u_long cFilterInfosatepg::do_sum(u_long sum, u_char *buf, int nBytes) { - int nleft=nBytes; - u_short *w = (u_short*)buf; - - while (nleft > 1) - { - sum += *w++; - nleft -= 2; - } - - if (nleft == 1) - { - u_short answer = 0; - *(u_char*)(&answer) = *(u_char*)w; - sum += answer; - } - return sum; + int nleft=nBytes; + u_short *w = (u_short*)buf; + + while (nleft > 1) + { + sum += *w++; + nleft -= 2; + } + + if (nleft == 1) + { + u_short answer = 0; + *(u_char*)(&answer) = *(u_char*)w; + sum += answer; + } + return sum; } u_short cFilterInfosatepg::foldsum(u_long sum) { - while (sum>>16) - sum = (sum >> 16) + (sum & 0xFFFF); + while (sum>>16) + sum = (sum >> 16) + (sum & 0xFFFF); - return ((u_short) ~sum); + return ((u_short) ~sum); } u_short cFilterInfosatepg::IPChecksum(iphdr *ipHeader) { - return foldsum(do_sum(0, (u_char*) ipHeader, sizeof(iphdr))); + return foldsum(do_sum(0, (u_char*) ipHeader, sizeof(iphdr))); } /* IpChecksum() */ u_short cFilterInfosatepg::UDPChecksum(iphdr *ipHeader, udphdr *udpHeader) { - u_long sum = 0; + u_long sum = 0; - // Ip-Pseudo-Header - sum = do_sum(sum, (u_char*)(&ipHeader->saddr), sizeof(ipHeader->saddr)); - sum = do_sum(sum, (u_char*)(&ipHeader->daddr), sizeof(ipHeader->daddr)); - sum += udpHeader->len; - sum += ipHeader->protocol<<8; + // Ip-Pseudo-Header + sum = do_sum(sum, (u_char*)(&ipHeader->saddr), sizeof(ipHeader->saddr)); + sum = do_sum(sum, (u_char*)(&ipHeader->daddr), sizeof(ipHeader->daddr)); + sum += udpHeader->len; + sum += ipHeader->protocol<<8; - sum = do_sum(sum, (u_char*)udpHeader, ntohs(udpHeader->len)); + sum = do_sum(sum, (u_char*)udpHeader, ntohs(udpHeader->len)); - return foldsum(sum); + return foldsum(sum); } - void cFilterInfosatepg::Process(u_short Pid, u_char Tid, const u_char *Data, int Length) { #define SECT_IP_HDR_START 12 @@ -77,111 +76,112 @@ void cFilterInfosatepg::Process(u_short Pid, u_char Tid, const u_char *Data, int #define SECT_IS_HDR_START 40 #define SECT_IS_DATA_START 52 - if (Data[0]!=0x3E) return; + if (Data[0]!=0x3E) return; - struct ethhdr eth_hdr; - memset(ð_hdr,0,sizeof(struct ethhdr)); + struct ethhdr eth_hdr; + memset(ð_hdr,0,sizeof(struct ethhdr)); - eth_hdr.h_dest[0]=Data[11]; - eth_hdr.h_dest[1]=Data[10]; - eth_hdr.h_dest[2]=Data[9]; - eth_hdr.h_dest[3]=Data[8]; - eth_hdr.h_dest[4]=Data[4]; - eth_hdr.h_dest[5]=Data[3]; + eth_hdr.h_dest[0]=Data[11]; + eth_hdr.h_dest[1]=Data[10]; + eth_hdr.h_dest[2]=Data[9]; + eth_hdr.h_dest[3]=Data[8]; + eth_hdr.h_dest[4]=Data[4]; + eth_hdr.h_dest[5]=Data[3]; - if (!global->CheckMAC(ð_hdr)) return; + // check mac and range + if (!global->CheckMAC(ð_hdr)) return; - int mac = eth_hdr.h_dest[5]; + int mac = eth_hdr.h_dest[5]; - struct iphdr *ip_hdr = (iphdr *) &Data[SECT_IP_HDR_START]; - struct udphdr *udp_hdr = (udphdr *) &Data[SECT_UDP_HDR_START]; + struct iphdr *ip_hdr = (iphdr *) &Data[SECT_IP_HDR_START]; + struct udphdr *udp_hdr = (udphdr *) &Data[SECT_UDP_HDR_START]; - // Only IPv4 - if (ip_hdr->version!=4) return; + // Only IPv4 + if (ip_hdr->version!=4) return; - // Check IP checksum - if (IPChecksum(ip_hdr)!=0) - { - dsyslog("infosatepg: ip checksum error"); - return; - } + // Check IP checksum + if (IPChecksum(ip_hdr)!=0) + { + dsyslog("infosatepg: ip checksum error"); + return; + } - // Only UDP - if (ip_hdr->protocol!=17) return; + // Only UDP + if (ip_hdr->protocol!=17) return; - // Check UDP checksum - if (UDPChecksum(ip_hdr,udp_hdr)!=0) - { - dsyslog("infosatepg: udp checksum error"); - return; - } + // Check UDP checksum + if (UDPChecksum(ip_hdr,udp_hdr)!=0) + { + dsyslog("infosatepg: udp checksum error"); + return; + } - struct infosathdr *ishdr = (struct infosathdr*) &Data[SECT_IS_HDR_START]; + struct infosathdr *ishdr = (struct infosathdr*) &Data[SECT_IS_HDR_START]; - if (ntohs(ishdr->technisatId)!=0x0001) return; + if (ntohs(ishdr->technisatId)!=0x0001) return; - const u_char *infosatdata = &Data[SECT_IS_DATA_START]; - int len = Length - SECT_IS_DATA_START-4; + const u_char *infosatdata = &Data[SECT_IS_DATA_START]; + int len = Length - SECT_IS_DATA_START-4; - char file[1024]; - snprintf(file,sizeof(file),"%s/infosatepg%02i%02i_%03i.dat",global->Directory(),ishdr->day,ishdr->month, - ntohs(ishdr->pktcnt)); + char file[1024]; + snprintf(file,sizeof(file),"%s/infosatepg%02i%02i_%03i.dat",global->Directory(),ishdr->day,ishdr->month, + ntohs(ishdr->pktcnt)); - if (global->Infosatdata[mac].NeverSeen(ishdr->day,ishdr->month,ntohs(ishdr->pktcnt))) - { - // never seen such a packet -> init structure - global->Infosatdata[mac].Init(file,ishdr->day,ishdr->month,ntohs(ishdr->pktcnt)); - } + if (global->Infosatdata[mac].NeverSeen(ishdr->day,ishdr->month,ntohs(ishdr->pktcnt))) + { + // never seen such a packet -> init structure + global->Infosatdata[mac].Init(file,ishdr->day,ishdr->month,ntohs(ishdr->pktcnt)); + } - // Check if we already have this packet - if (global->Infosatdata[mac].GetBit(ntohs(ishdr->pktnr))) return; + // Check if we already have this packet + if (global->Infosatdata[mac].GetBit(ntohs(ishdr->pktnr))) return; - // set bit in Infosatdata bitfield - global->Infosatdata[mac].SetBit(ntohs(ishdr->pktnr),true); + // set bit in Infosatdata bitfield + global->Infosatdata[mac].SetBit(ntohs(ishdr->pktnr),true); #ifdef VDRDEBUG - dsyslog("infosatepg: mac=%02x-%02x-%02x-%02x-%02x-%02x",eth_hdr.h_dest[0],eth_hdr.h_dest[1], - eth_hdr.h_dest[2],eth_hdr.h_dest[3],eth_hdr.h_dest[4],eth_hdr.h_dest[5] ); + dsyslog("infosatepg: mac=%02x-%02x-%02x-%02x-%02x-%02x",eth_hdr.h_dest[0],eth_hdr.h_dest[1], + eth_hdr.h_dest[2],eth_hdr.h_dest[3],eth_hdr.h_dest[4],eth_hdr.h_dest[5] ); - dsyslog("infosatepg: tid=%04i tbl=%04i stbl=%04i day=%02i month=%02i pktnr=%03i pktcnt=%03i len=%i", - ntohs(ishdr->technisatId),ishdr->tableId,ishdr->tablesubId,ishdr->day, - ishdr->month, ntohs(ishdr->pktnr), ntohs(ishdr->pktcnt), len); + dsyslog("infosatepg: tid=%04i tbl=%04i stbl=%04i day=%02i month=%02i pktnr=%03i pktcnt=%03i len=%i", + ntohs(ishdr->technisatId),ishdr->tableId,ishdr->tablesubId,ishdr->day, + ishdr->month, ntohs(ishdr->pktnr), ntohs(ishdr->pktcnt), len); - dsyslog("infosatepg: save to %s", file); + dsyslog("infosatepg: save to %s", file); #endif - int f=open(file,O_RDWR|O_CREAT,0664); - if (f==-1) - { - if (errno!=ENOSPC) + int f=open(file,O_RDWR|O_CREAT,0664); + if (f==-1) { - esyslog("infosatepg: unable to create file '%s'", file); + if (errno!=ENOSPC) + { + esyslog("infosatepg: unable to create file '%s'", file); + } + return; } - return; - } - off_t offset = (off_t) (ntohs(ishdr->pktnr)*1400); - if (lseek(f,offset,SEEK_SET)!=(off_t) -1) - { + off_t offset = (off_t) (ntohs(ishdr->pktnr)*1400); + if (lseek(f,offset,SEEK_SET)!=(off_t) -1) + { #ifdef VDRDEBUG - dsyslog("infosatepg: writing to %li",offset); + dsyslog("infosatepg: writing to %li",offset); #endif - write(f,infosatdata,len); - } - close(f); + write(f,infosatdata,len); + } + close(f); #ifdef WRITE_RAW - sprintf(file,"%s/%03i.dat",dir,ntohs(ishdr->pktnr)); - f=open(file,O_RDWR|O_CREAT,0664); - if (f==-1) return; - write(f,Data,Length); - close(f); + sprintf(file,"%s/%03i.dat",dir,ntohs(ishdr->pktnr)); + f=open(file,O_RDWR|O_CREAT,0664); + if (f==-1) return; + write(f,Data,Length); + close(f); #endif - // check if we have all packets - if (global->Infosatdata[mac].ReceivedAll()) - { - // we have all packets - isyslog("infosatepg: day=%02i month=%02i fully received", ishdr->day,ishdr->month); - } + // check if we have all packets + if (global->Infosatdata[mac].CheckReceivedAll()) + { + // we have all packets + isyslog("infosatepg: day=%02i month=%02i fully received", ishdr->day,ishdr->month); + } } diff --git a/global.cpp b/global.cpp index 348d940..86dcb06 100644 --- a/global.cpp +++ b/global.cpp @@ -8,7 +8,7 @@ cGlobalInfosatdata::cGlobalInfosatdata() Init(NULL,0,0,0); } -bool cGlobalInfosatdata::NeverSeen(int Day, int Month, int Packetcount) +bool cGlobalInfosatdata::NeverSeen(int Day,int Month,int Packetcount) { if ((day!=Day) || (month!=Month) || (pktcnt!=Packetcount)) { @@ -20,15 +20,16 @@ bool cGlobalInfosatdata::NeverSeen(int Day, int Month, int Packetcount) } } -void cGlobalInfosatdata::Init(char *File, int Day, int Month, int Packetcount) +void cGlobalInfosatdata::Init(char *File,int Day,int Month,int Packetcount) { if (access(file,R_OK)==0) { dsyslog("infosatepg: deleting old %s",file); unlink(file); } - ready=false; - processed=false; + Processed=false; + receivedall=false; + receivedpercent=0; day=Day; month=Month; pktcnt=Packetcount; @@ -40,41 +41,45 @@ void cGlobalInfosatdata::Init(char *File, int Day, int Month, int Packetcount) int cGlobalInfosatdata::Save(int fd) { if (fd==-1) return -1; - ssize_t ret=write(fd,&ready,sizeof(ready)); - if (ret!=sizeof(ready)) return -1; - ret=write(fd,&processed,sizeof(processed)); - if (ret!=sizeof(processed)) return -1; - ret=write(fd,&day,sizeof(day)); + ssize_t ret=write(fd,&receivedall,sizeof(receivedall)); + if (ret!=sizeof(receivedall)) return -1; + ret=write(fd,&receivedpercent,sizeof(receivedpercent)); + if (ret!=sizeof(receivedpercent)) return -1; + ret=write(fd,&Processed,sizeof(Processed)); + if (ret!=sizeof(Processed)) return -1; + ret=write (fd,&day,sizeof (day)); if (ret!=sizeof(day)) return -1; - ret=write(fd,&month,sizeof(month)); - if (ret!=sizeof(month)) return -1; - ret=write(fd,&pktcnt,sizeof(pktcnt)); - if (ret!=sizeof(pktcnt)) return -1; - ret=write(fd,&bitfield,sizeof(bitfield)); - if (ret!=sizeof(bitfield)) return -1; - ret=write(fd,&file,sizeof(file)); - if (ret!=sizeof(file)) return -1; + ret=write (fd,&month,sizeof (month)); + if (ret!=sizeof (month)) return -1; + ret=write (fd,&pktcnt,sizeof (pktcnt)); + if (ret!=sizeof (pktcnt)) return -1; + ret=write (fd,&bitfield,sizeof (bitfield)); + if (ret!=sizeof (bitfield)) return -1; + ret=write (fd,&file,sizeof (file)); + if (ret!=sizeof (file)) return -1; return ret; } int cGlobalInfosatdata::Load(int fd) { if (fd==-1) return -1; - ssize_t ret=read(fd,&ready,sizeof(ready)); - if (ret!=sizeof(ready)) return -1; - ret=read(fd,&processed,sizeof(processed)); - if (ret!=sizeof(processed)) return -1; - ret=read(fd,&day,sizeof(day)); - if (ret!=sizeof(day)) return -1; - ret=read(fd,&month,sizeof(month)); - if (ret!=sizeof(month)) return -1; - ret=read(fd,&pktcnt,sizeof(pktcnt)); - if (ret!=sizeof(pktcnt)) return -1; - ret=read(fd,&bitfield,sizeof(bitfield)); - if (ret!=sizeof(bitfield)) return -1; - ret=read(fd,&file,sizeof(file)); - if (ret!=sizeof(file)) return -1; - dsyslog("infosatepg: loaded file=*%s*",file); + ssize_t ret=read (fd,&receivedall,sizeof (receivedall)); + if (ret!=sizeof (receivedall)) return -1; + ret=read (fd,&receivedpercent,sizeof(receivedpercent)); + if (ret!=sizeof (receivedpercent)) return -1; + ret=read (fd,&Processed,sizeof (Processed)); + if (ret!=sizeof (Processed)) return -1; + ret=read (fd,&day,sizeof (day)); + if (ret!=sizeof (day)) return -1; + ret=read (fd,&month,sizeof (month)); + if (ret!=sizeof (month)) return -1; + ret=read (fd,&pktcnt,sizeof (pktcnt)); + if (ret!=sizeof (pktcnt)) return -1; + ret=read (fd,&bitfield,sizeof (bitfield)); + if (ret!=sizeof (bitfield)) return -1; + ret=read (fd,&file,sizeof (file)); + if (ret!=sizeof (file)) return -1; + dsyslog ("infosatepg: loaded file=%s",file); return ret; } @@ -82,38 +87,42 @@ int cGlobalInfosatdata::Load(int fd) void cGlobalInfosatdata::Debug(const char *Directory) { char file[1024]; - snprintf(file,sizeof(file),"%s/infosatepg9999_999.dat",Directory); - Init(file,99,99,999); + snprintf (file,sizeof (file),"%s/infosatepg9999_999.dat",Directory); + Init (file,99,99,999); ready=true; } #endif -int cGlobalInfosatdata::ReceivedPercent() +bool cGlobalInfosatdata::CheckReceivedAll() { - if (pktcnt==0) return 0; int donecnt=0; - for (int i=0; inuminfosatchannels)) return; + int i; + for (i=Index; i<(numinfosatchannels-1); i++) + { + infosatchannels[i].ChannelID=infosatchannels[i+1].ChannelID; + infosatchannels[i].Usage=infosatchannels[i+1].Usage; + } + //infosatchannels[numinfosatchannels].Usage=0; + numinfosatchannels--; +} + tChannelID cGlobalInfosatepg::GetChannelID(int Index) { if (numinfosatchannels==0) return tChannelID::InvalidID; @@ -224,14 +240,14 @@ int cGlobalInfosatepg::GetChannelUse(int Index) int cGlobalInfosatepg::Save() { char file[1024]; - snprintf(file,sizeof(file),"%s/infosatepg.dat",directory); + snprintf (file,sizeof (file),"%s/infosatepg.dat",directory); - int f=open(file,O_RDWR|O_CREAT|O_TRUNC,0664); + int f=open (file,O_RDWR|O_CREAT|O_TRUNC,0664); if (f==-1) { if (errno!=ENOSPC) { - esyslog("infosatepg: unable to create file '%s'", file); + esyslog ("infosatepg: unable to create file '%s'", file); } return -1; } @@ -239,97 +255,140 @@ int cGlobalInfosatepg::Save() int ret; for (int mac=EPG_FIRST_DAY_MAC; mac<=EPG_LAST_DAY_MAC; mac++) { - ret=Infosatdata[mac].Save(f); + ret=Infosatdata[mac].Save (f); if (ret==-1) break; } if (ret!=-1) { - ret=write(f,&this_day,sizeof(this_day)); - if (ret!=sizeof(this_day)) ret=-1; + ret=write (f,&this_day,sizeof(this_day)); + if (ret!=sizeof (this_day)) ret=-1; } if (ret!=-1) { - ret=write(f,&this_month,sizeof(this_month)); - if (ret!=sizeof(this_month)) ret=-1; + ret=write (f,&this_month,sizeof(this_month)); + if (ret!=sizeof (this_month)) ret=-1; + } + if (ret!=-1) + { + ret=write (f,&wakeuptime,sizeof(wakeuptime)); + if (ret!=sizeof (wakeuptime)) ret=-1; } - close(f); - if (ret==-1) unlink(file); + close (f); + if (ret==-1) unlink (file); return ret; } int cGlobalInfosatepg::Load() { char file[1024]; - snprintf(file,sizeof(file),"%s/infosatepg.dat",directory); + snprintf (file,sizeof (file),"%s/infosatepg.dat",directory); - int f=open(file,O_RDONLY); + int f=open (file,O_RDONLY); if (f==-1) return 0; // it's ok if the file doesn't exist int ret; for (int mac=EPG_FIRST_DAY_MAC; mac<=EPG_LAST_DAY_MAC; mac++) { - ret=Infosatdata[mac].Load(f); + ret=Infosatdata[mac].Load (f); if (ret==-1) break; } if (ret!=-1) { - ret=read(f,&this_day,sizeof(this_day)); - if (ret!=sizeof(this_day)) ret=-1; + ret=read (f,&this_day,sizeof (this_day)); + if (ret!=sizeof (this_day)) ret=-1; } if (ret!=-1) { - ret=read(f,&this_month,sizeof(this_month)); - if (ret!=sizeof(this_month)) ret=-1; + ret=read (f,&this_month,sizeof (this_month)); + if (ret!=sizeof (this_month)) ret=-1; + } + if (ret!=-1) + { + ret=read (f,&wakeuptime,sizeof (wakeuptime)); + if (ret!=sizeof (wakeuptime)) ret=-1; } - close(f); + close (f); if (ret==-1) { - unlink(file); // but it's not ok if the read failed! - for (int mac=EPG_FIRST_DAY_MAC; mac<=EPG_LAST_DAY_MAC; mac++) - { - Infosatdata[mac].Init(NULL,0,0,0); - } - + unlink (file); // but it's not ok if the read failed! + ResetReceivedAll(); } return ret; } -void cGlobalInfosatepg::ResetProcessedFlags(void) +void cGlobalInfosatepg::ResetReceivedAll(void) +{ + for (int mac=EPG_FIRST_DAY_MAC; mac<=EPG_LAST_DAY_MAC; mac++) + { + Infosatdata[mac].ResetReceivedAll(); + } + wakeuptime=-1; +} + +void cGlobalInfosatepg::ResetProcessed (void) { - dsyslog("infosatepg: reprocess files (later)"); for (int mac=EPG_FIRST_DAY_MAC; mac<=EPG_LAST_DAY_MAC; mac++) { - Infosatdata[mac].ResetProcessed(); + Infosatdata[mac].Processed=false; } + wakeuptime=-1; + ProcessedAll=false; } -void cGlobalInfosatepg::Lock(time_t Now) +bool cGlobalInfosatepg::ReceivedAll(int *Day, int *Month) { + bool res=false; + time_t Now=time (NULL); struct tm tm; - if (!localtime_r(&Now,&tm)) + if (!localtime_r (&Now,&tm)) return false; + + // First check if we have received all data + int numReceived=0; + for (int mac=EPG_FIRST_DAY_MAC; mac<=EPG_LAST_DAY_MAC; mac++) { - this_day=-1; - this_month=-1; + if (Infosatdata[mac].ReceivedAll()) numReceived++; } - else + // All days fully received + if (numReceived==EPG_DAYS) { - if ((tm.tm_mday!=this_day) || ((tm.tm_mon+1)!=this_month)) - isyslog("infosatepg: all data processed"); - this_day=tm.tm_mday; - this_month=tm.tm_mon+1; + // First entry from today? + if ((Infosatdata[EPG_FIRST_DAY_MAC].Day() ==tm.tm_mday) && + (Infosatdata[EPG_FIRST_DAY_MAC].Month() ==tm.tm_mon+1)) + { + // Yes + if ((this_day!=tm.tm_mday) || (this_month!=tm.tm_mon+1)) + { + isyslog ("infosatepg: all data received"); + this_day=tm.tm_mday; + this_month=tm.tm_mon+1; + } + res=true; + } + else + { + // New day, but new data is ready only after wakeup-time + time_t Now = time(NULL); + time_t Time = cTimer::SetTime(Now,cTimer::TimeToInt(WakeupTime())); + if (Now>=Time) + { + // new day and new data should be available + ResetReceivedAll(); + res=false; + } + else + { + // wait till we are after wakeuptime + res=true; + } + + } } -} -bool cGlobalInfosatepg::isLocked(int *Day, int *Month) -{ if (Day) *Day=this_day; if (Month) *Month=this_month; - time_t Now=time(NULL); - struct tm tm; - if (!localtime_r(&Now,&tm)) return false; - if ((tm.tm_mday==this_day) && ((tm.tm_mon+1)==this_month)) return true; - return false; + + return res; } diff --git a/global.h b/global.h index 8046b0f..0201758 100644 --- a/global.h +++ b/global.h @@ -13,6 +13,8 @@ #include #include +#include +#include #define MIN_WAITTIME 10 #define MAX_WAITTIME 120 @@ -21,14 +23,14 @@ class cGlobalInfosatdata { -#define _GetByte( ptr, bitnum ) ( (((char*)ptr)+bitnum/8) ) -#define _GetBit( ptr, bitnum ) ( (*_GetByte(ptr, bitnum) >> (bitnum%8)) & 1 ) -#define _SetBit( ptr, bitnum, val ) ( val ? \ +#define _GetByte(ptr, bitnum) ((((char*)ptr)+bitnum/8)) +#define _GetBit(ptr, bitnum) ((*_GetByte(ptr, bitnum) >> (bitnum%8)) & 1) +#define _SetBit(ptr, bitnum, val) (val ? \ (*_GetByte(ptr, bitnum) |= (1<<(bitnum%8))) : \ - (*_GetByte(ptr, bitnum) &= ~(1<<(bitnum%8))) ) + (*_GetByte(ptr, bitnum) &= ~(1<<(bitnum%8)))) private: - bool ready; - bool processed; + bool receivedall; + int receivedpercent; u_char day; u_char month; u_short pktcnt; @@ -36,13 +38,19 @@ private: char file[1024]; public: cGlobalInfosatdata(); - bool isReady2Process() + bool Processed; + bool ReceivedAll() { - return (ready && !processed); + return receivedall; } - bool wasProcessed() + void ResetReceivedAll() { - return (ready && processed); + Init(file,0,0,0); + } + bool CheckReceivedAll(); + int ReceivedPercent() + { + return receivedpercent; } int Day() { @@ -52,39 +60,24 @@ public: { return month; } - int Packetcount() - { - return pktcnt; - } - void SetProcessed() - { - processed=true; - } - void ResetProcessed() - { - processed=false; - } - bool GetBit(int Bitnumber) + bool GetBit (int Bitnumber) { - return _GetBit(bitfield,Bitnumber); + return _GetBit (bitfield,Bitnumber); } - void SetBit(int Bitnumber,bool Value) + void SetBit (int Bitnumber,bool Value) { - _SetBit(bitfield,Bitnumber,Value); + _SetBit (bitfield,Bitnumber,Value); } - const char *GetFile() const + const char *GetFile() const // used in process.cpp { return (char *) &file; } - - bool NeverSeen(int Day, int Month, int Packetcount); - void Init(char *File, int Day, int Month, int Packetcount); - bool ReceivedAll(); - int ReceivedPercent(); - int Load(int fd); - int Save(int fd); + bool NeverSeen (int Day, int Month, int Packetcount); + void Init (char *File, int Day, int Month, int Packetcount); + int Load (int fd); + int Save (int fd); #ifdef INFOSATEPG_DEBUG - void Debug(const char *Directory); + void Debug (const char *Directory); #endif }; @@ -121,62 +114,74 @@ private: const char *directory; u_char MAC[5]; time_t timer; - bool Switched; + bool switched; int this_day; int this_month; + int numinfosatchannels; + int wakeuptime; + struct infosatchannels *infosatchannels; + void ResetReceivedAll(void); public: cGlobalInfosatepg(); ~cGlobalInfosatepg(); + cGlobalInfosatdata Infosatdata[EPG_DAYS+1]; + cDevice *dev; + void SetWakeupTime(int Time) + { + if (Time==-1) return; + if (wakeuptime!=-1) return; // already set + int hour,minute; + hour=(int) (wakeuptime/100); + minute=wakeuptime-(hour*100); + isyslog("infosatepg: wakeup set to %02i:%02i", hour,minute); + wakeuptime=Time; + } + int WakeupTime() + { + return wakeuptime; + } + int LastCurrentChannel; int Channel; int Pid; int EventTimeDiff; int WaitTime; - int WakeupTime; // 0100 = 01:00 1222 = 12:22 - const char *Directory() { return directory; } - bool SetDirectory(const char *Directory); - bool CheckMAC(struct ethhdr *eth_hdr); - void SetTimer() + bool SetDirectory (const char *Directory); + bool CheckMAC (struct ethhdr *eth_hdr); + void SetWaitTimer() { - timer=time(NULL); + timer=time (NULL); } - bool isWaitOk() + bool WaitOk() { - return (time(NULL)>(timer+(time_t) WaitTime)); + return (time (NULL) > (timer+ (time_t) WaitTime)); } - void SetSwitched(bool Value) + void SetSwitched (bool Value) { - Switched=Value; + switched=Value; } - bool isSwitched() + bool Switched() { - return Switched; + return switched; } - -public: - cGlobalInfosatdata Infosatdata[EPG_DAYS+1]; int Load(); int Save(); - void Lock(time_t Now); - bool isLocked(int *Day, int *Month); - bool isLocked() - { - return isLocked(NULL,NULL); - } - -private: - int numinfosatchannels; - struct infosatchannels *infosatchannels; -public: - void AddChannel(tChannelID ChannelID,int Usage); - tChannelID GetChannelID(int Index); - bool SetChannelUse(int Index,int Usage); - void ResetProcessedFlags(void); - int GetChannelUse(int Index); - bool ChannelExists(tChannelID ChannelID,int *Index); + bool ProcessedAll; + bool ReceivedAll (int *Day, int *Month); + bool ReceivedAll() + { + return ReceivedAll (NULL,NULL); + } + void AddChannel (tChannelID ChannelID,int Usage); + void RemoveChannel(int Index); + tChannelID GetChannelID (int Index); + bool SetChannelUse (int Index,int Usage); + void ResetProcessed (void); + int GetChannelUse (int Index); + bool ChannelExists (tChannelID ChannelID,int *Index); int InfosatChannels() { return numinfosatchannels; diff --git a/infosatepg.cpp b/infosatepg.cpp index 89ae1b6..60a07a9 100644 --- a/infosatepg.cpp +++ b/infosatepg.cpp @@ -78,7 +78,18 @@ bool cPluginInfosatepg::ProcessArgs(int argc, char *argv[]) bool cPluginInfosatepg::Initialize(void) { - // Initialize any background activities the plugin shall perform. + // Initialize plugin - check channellist + tChannelID ChannelID; + for (int i=0; iInfosatChannels(); i++) + { + ChannelID=global->GetChannelID(i); + if (!Channels.GetByChannelID(ChannelID)) + { + dsyslog("infosatepg: remove %s",*ChannelID.ToString()); + global->RemoveChannel(i); + // Removing entries from setup.conf is not possible! + } + } return true; } @@ -110,83 +121,119 @@ void cPluginInfosatepg::Stop(void) void cPluginInfosatepg::Housekeeping(void) { // Perform any cleanup or other regular tasks. - int numProcessed=0; for (int mac=EPG_FIRST_DAY_MAC; mac<=EPG_LAST_DAY_MAC; mac++) { - if (global->Infosatdata[mac].isReady2Process()) - { - isyslog("infosatepg: janitor found data to be processed: day=%i month=%i", - global->Infosatdata[mac].Day(),global->Infosatdata[mac].Month()); - cProcessInfosatepg process(mac,global); - } - if (global->Infosatdata[mac].wasProcessed()) + if (global->Infosatdata[mac].ReceivedAll() & !global->Infosatdata[mac].Processed) { - numProcessed++; + isyslog ("infosatepg: janitor found data to be processed: day=%i month=%i", + global->Infosatdata[mac].Day(),global->Infosatdata[mac].Month()); + cProcessInfosatepg process (mac,global); } } - if (numProcessed==EPG_DAYS) + int numprocessed=0; + for (int mac=EPG_FIRST_DAY_MAC; mac<=EPG_LAST_DAY_MAC; mac++) { - global->Lock(time(NULL)); + if (global->Infosatdata[mac].Processed) numprocessed++; } + if (numprocessed==EPG_DAYS) global->ProcessedAll=true; + + } void cPluginInfosatepg::MainThreadHook(void) { // Perform actions in the context of the main program thread. - if ((!global->isWaitOk()) || (global->isSwitched()) || (global->isLocked())) return; + if ((!global->WaitOk()) || (global->Switched()) || (global->ReceivedAll())) return; cChannel *chan=Channels.GetByNumber(global->Channel); if (!chan) return; + if (ShutdownHandler.IsUserInactive()) + { + // we are idle -> use live device if we can + cDevice *dev; + dev=cDevice::ActualDevice(); + if (dev->ProvidesTransponder(chan) && !dev->Receiving()) + { + // ok -> use this device + dsyslog("infosatepg: found free device %i (live)",dev->DeviceNumber()+1); + global->dev=dev; + if (global->LastCurrentChannel==-1) global->LastCurrentChannel= + cDevice::PrimaryDevice()->CurrentChannel(); + cDevice::PrimaryDevice()->SwitchChannel(chan,true); + global->SetWaitTimer(); + return; + } + } + + // Cannot use live device try another (if possible) + for (int i=0; iIsTunedToTransponder(chan)) return; // device is already tuned to transponder -> ok if (!dev->ProvidesTransponder(chan)) continue; // device cannot provide transponder -> skip - if (EITScanner.UsesDevice(dev)) continue; // EITScanner is updating EPG -> skip - if (dev->Receiving()) continue; // device is recording -> skip - - if (dev->IsPrimaryDevice()) + if (dev->IsTunedToTransponder(chan)) { - // just use primary ff-card if inactive - if (!ShutdownHandler.IsUserInactive()) continue; // not idle -> skip - } - - if (cDevice::ActualDevice()->CardIndex()==i) - { - // LIVE device without recording, just use if inactive - if (!ShutdownHandler.IsUserInactive()) continue; // not idle -> skip - live=true; + // just use this device + dsyslog("infosatepg: found already switched device %i",dev->DeviceNumber()+1); + global->dev=dev; + if (cDevice::ActualDevice()->CardIndex()==i) + cDevice::PrimaryDevice()->SwitchChannel(chan,true); + else + dev->SwitchChannel(chan,false); + global->SetWaitTimer(); + return; } + if (EITScanner.UsesDevice(dev)) continue; // EITScanner is updating EPG -> skip + if (dev->Receiving()) continue; // device is recording -> skip + if (dev->IsPrimaryDevice()) continue; // device is primary -> skip + if (cDevice::ActualDevice()->CardIndex()==i) continue; // device is live viewing -> skip // ok -> use this device dsyslog("infosatepg: found free device %i",dev->DeviceNumber()+1); - dev->SwitchChannel(chan,live); - global->SetTimer(); + global->dev=dev; + dev->SwitchChannel(chan,false); + global->SetWaitTimer(); return; } } + } cString cPluginInfosatepg::Active(void) { - // Returns a message string if shutdown should be postponed - if (!global->isLocked()) + // Returns a message string if we are not ready + if (!global->ProcessedAll) return tr("Infosat plugin still working"); + + // we are done + if (global->LastCurrentChannel!=-1) + { + // we switched from users last channel + if (cDevice::PrimaryDevice()->CurrentChannel()==global->Channel) + { + // we are still on infosatepg channel + cChannel *chan=Channels.GetByNumber(global->Channel); + if (chan) + { + // switch back to users last viewed channel + cDevice::PrimaryDevice()->SwitchChannel(chan,true); + } + } + } return NULL; } time_t cPluginInfosatepg::WakeupTime(void) { // Returns custom wakeup time for shutdown script - if (!global->WakeupTime) return 0; + if (global->WakeupTime()==-1) global->SetWakeupTime(300); // just to be safe time_t Now = time(NULL); - time_t Time = cTimer::SetTime(Now,cTimer::TimeToInt(global->WakeupTime)); + time_t Time = cTimer::SetTime(Now,cTimer::TimeToInt(global->WakeupTime())); if (Time <= Now) - Time = cTimer::IncDay(Time,1); + Time = cTimer::IncDay(Time,1); return Time; } @@ -198,7 +245,7 @@ cOsdObject *cPluginInfosatepg::MainMenuAction(void) cMenuSetupPage *cPluginInfosatepg::SetupMenu(void) { - // Returns the setup menu. + // Return the setup menu. return new cMenuSetupInfosatepg(global); } @@ -209,7 +256,6 @@ bool cPluginInfosatepg::SetupParse(const char *Name, const char *Value) else if (!strcasecmp(Name,"Pid")) global->Pid=atoi(Value); else if (!strcasecmp(Name,"WaitTime")) global->WaitTime=atoi(Value); else if (!strcasecmp(Name,"EventTimeDiff")) global->EventTimeDiff=60*atoi(Value); - else if (!strcasecmp(Name,"WakeupTime")) global->WakeupTime=atoi(Value); else if (!strncasecmp(Name,"Channel",7)) { if (strlen(Name)<10) return false; @@ -247,17 +293,36 @@ cString cPluginInfosatepg::SVDRPCommand(const char *Command, const char *Option, { int day,month; asprintf(&output,"InfosatEPG state:\n"); - if (global->isLocked(&day,&month)) - asprintf(&output,"%s Locked: yes (%02i.%02i)",output,day,month); + if (global->ReceivedAll(&day,&month)) + asprintf(&output,"%s Received all: yes (%02i.%02i.)",output,day,month); else - asprintf(&output,"%s Locked: no",output); - asprintf(&output,"%s Switched: %s\n",output,global->isSwitched() ? "yes" : "no"); + asprintf(&output,"%s Received all: no",output); + asprintf(&output,"%s Processed all: %s",output,global->ProcessedAll ? "yes" : "no"); + if (global->Switched()) + { + asprintf(&output,"%s Switched: yes (%i)\n",output,global->dev->DeviceNumber()+1); + } + else + { + asprintf(&output,"%s Switched: no\n",output); + } + if (global->WakeupTime()!=-1) + { + int hour,minute; + hour=(int) (global->WakeupTime()/100); + minute=global->WakeupTime()-(hour*100); + asprintf(&output,"%s WakeupTime: %02i:%02i\n", output,hour,minute); + } + else + { + asprintf(&output,"%s WakeupTime: unset\n", output); + } for (int mac=EPG_FIRST_DAY_MAC; mac<=EPG_LAST_DAY_MAC; mac++) { asprintf(&output,"%s Day %i (%02i.%02i.): %3i%% %s\n", output,mac,global->Infosatdata[mac].Day(),global->Infosatdata[mac].Month(), global->Infosatdata[mac].ReceivedPercent(), - global->Infosatdata[mac].wasProcessed() ? "processed" : ""); + global->Infosatdata[mac].Processed ? "processed" : ""); } } return output; diff --git a/po/de_DE.po b/po/de_DE.po index 330d49d..cbaf0dc 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-1.6.0\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2008-12-21 19:39+0100\n" +"POT-Creation-Date: 2009-01-02 01:28+0100\n" "PO-Revision-Date: 2008-05-02 16:20+0200\n" "Last-Translator: Jochen Dolze \n" "Language-Team: \n" @@ -39,12 +39,6 @@ msgstr "Wartezeit [s]" msgid "Time difference [min]" msgstr "Zeitdifferenz [min]" -msgid "Wakeup options" -msgstr "Weck-Optionen" - -msgid "Wakeup time" -msgstr "Weckzeit" - msgid "Infosat channels" msgstr "Infosat Kanäle" diff --git a/process.cpp b/process.cpp index 47d5563..fde84be 100644 --- a/process.cpp +++ b/process.cpp @@ -140,9 +140,11 @@ cProcessInfosatepg::cProcessInfosatepg(int Mac, cGlobalInfosatepg *Global) f=fopen(file,"r"); if (f) { - if (ParseInfosatepg(f)) + int firststarttime=-1; + if (ParseInfosatepg(f,&firststarttime)) { - Global->Infosatdata[Mac].SetProcessed(); + global->SetWakeupTime(firststarttime); + global->Infosatdata[Mac].Processed=true; } else { @@ -200,8 +202,8 @@ bool cProcessInfosatepg::AddInfosatEvent(cChannel *channel, cInfosatevent *iEven if (!Event) Event= (cEvent *) SearchEvent(Schedule,iEvent); if (!Event) return true; // just bail out with ok - start=iEvent->StartTime(); - dsyslog("infosatepg: ievent %s [%s]", iEvent->Title(),ctime(&start)); + start=iEvent->StartTime(); + dsyslog("infosatepg: ievent %s [%s]", iEvent->Title(),ctime(&start)); // change existing event Event->SetShortText(iEvent->ShortText()); @@ -321,7 +323,7 @@ bool cProcessInfosatepg::CheckAnnouncement(char *s,cInfosatevent *iEvent) return ret; } -bool cProcessInfosatepg::ParseInfosatepg(FILE *f) +bool cProcessInfosatepg::ParseInfosatepg(FILE *f,int *firststarttime) { char *s,tag; int fields,index; @@ -433,6 +435,14 @@ bool cProcessInfosatepg::ParseInfosatepg(FILE *f) if (!ievent) ievent = new cInfosatevent; tm.tm_hour=shour; tm.tm_min=sminute; + + if (*firststarttime==-1) + { + shour-=2; + if (shour<0) shour=24+shour; + *firststarttime=(shour*100)+sminute; + } + tm.tm_isdst=-1; time_t start=mktime(&tm); if ((oldstart!=(time_t) -1) && (difftime(start,oldstart)<0)) diff --git a/process.h b/process.h index 0edc68b..5c8ff1c 100644 --- a/process.h +++ b/process.h @@ -72,7 +72,7 @@ private: bool AddInfosatEvent(cChannel *channel, cInfosatevent *iEvent); bool CheckOriginal(char *s,cInfosatevent *iEvent,cCharSetConv *conv); bool CheckAnnouncement(char *s,cInfosatevent *iEvent); - bool ParseInfosatepg(FILE *f); + bool ParseInfosatepg(FILE *f,int *firststarttime); cChannel *GetInfosatChannel(int frequency, int sid); u_long DoSum(u_long sum, const char *buf, int nBytes); cEvent *SearchEvent(cSchedule* Schedule, cInfosatevent *iEvent); diff --git a/setup.cpp b/setup.cpp index 85521f5..1ab13d9 100644 --- a/setup.cpp +++ b/setup.cpp @@ -16,7 +16,6 @@ cMenuSetupInfosatepg::cMenuSetupInfosatepg(cGlobalInfosatepg *Global) newChannel = global->Channel; newPid = global->Pid; newWaitTime = global->WaitTime; - newWakeupTime = global->WakeupTime; newEventTimeDiff=(int) (global->EventTimeDiff/60); Add(NewTitle(tr("Scan parameter"))); @@ -28,9 +27,6 @@ cMenuSetupInfosatepg::cMenuSetupInfosatepg(cGlobalInfosatepg *Global) Add(new cMenuEditIntItem( tr("Time difference [min]"), &newEventTimeDiff, MIN_EVENTTIMEDIFF,MAX_EVENTTIMEDIFF)); - Add(NewTitle(tr("Wakeup options"))); - Add(new cMenuEditTimeItem(tr("Wakeup time"),&newWakeupTime)); - if (global->InfosatChannels()) { Add(NewTitle(tr("Infosat channels")),true); @@ -66,26 +62,30 @@ void cMenuSetupInfosatepg::Store(void) SetupStore("Pid", global->Pid = newPid); SetupStore("WaitTime", global->WaitTime = newWaitTime); SetupStore("EventTimeDiff", newEventTimeDiff); - SetupStore("WakeupTime",global->WakeupTime = newWakeupTime); global->EventTimeDiff = 60*newEventTimeDiff; - if (bReprocess) global->ResetProcessedFlags(); + if (bReprocess) + { + dsyslog("infosatepg: reprocess files (later)"); + global->ResetProcessed(); + } } eOSState cMenuSetupInfosatepg::Edit() { if (HasSubMenu() || Count()==0) - return osBack; + return osUnknown; + if (Current()>=chanCurrent) { int chanIndex=Current()-chanCurrent; if (chanIndexInfosatChannels()) return AddSubMenu(new cMenuSetupChannelMenu(global,chanIndex)); else - return osBack; + return osUnknown; } else - return osBack; + return osUnknown; } eOSState cMenuSetupInfosatepg::ProcessKey(eKeys Key) @@ -100,8 +100,12 @@ eOSState cMenuSetupInfosatepg::ProcessKey(eKeys Key) switch (Key) { case kOk: - state=Edit(); - if (state==osBack) Store(); + state=Edit(); + if (state==osUnknown) + { + Store(); + state=osBack; + } break; default: break; @@ -128,6 +132,7 @@ cMenuSetupChannelMenu::cMenuSetupChannelMenu(cGlobalInfosatepg *Global, int Inde if (newChannelUse<0) newChannelUse=USE_NOTHING; // to be safe! channel = Channels.GetByChannelID(global->GetChannelID(index)); + if (!channel) return; char *str; asprintf(&str,"---- %s ----", channel->Name()); @@ -151,5 +156,9 @@ void cMenuSetupChannelMenu::Store(void) if (global->SetChannelUse(index,newChannelUse)) bReprocess=true; SetupStore(name,newChannelUse); free(name); - if (bReprocess) global->ResetProcessedFlags(); + if (bReprocess) + { + dsyslog("infosatepg: reprocess files (later)"); + global->ResetProcessed(); + } } diff --git a/status.cpp b/status.cpp index b540f74..9f02ef8 100644 --- a/status.cpp +++ b/status.cpp @@ -26,7 +26,11 @@ void cStatusInfosatepg::ChannelSwitch(const cDevice *Device, int ChannelNumber) bool bAddFilter=false; // just add filter if we aren't locked - if ((ChannelNumber==global->Channel) && (!global->isLocked())) bAddFilter=true; + if (ChannelNumber==global->Channel) + { + if (Device!=global->dev) return; // don't use virtual devices (they will switch too) + if (!global->ReceivedAll()) bAddFilter=true; + } if (bAddFilter) { @@ -55,7 +59,8 @@ void cStatusInfosatepg::ChannelSwitch(const cDevice *Device, int ChannelNumber) dsyslog("infosatepg: detach filter"); myFilterDevice->Detach(myFilter); myFilterDevice=NULL; - global->SetTimer(); + global->dev=NULL; + global->SetWaitTimer(); global->SetSwitched(false); } } -- cgit v1.2.3