source: titan/titan/extepg.h @ 42143

Last change on this file since 42143 was 39308, checked in by Stephan, 7 years ago

tryfix next warnings

File size: 48.6 KB
Line 
1#ifndef EXTEPG_H
2#define EXTEPG_H
3
4//channel C+ DEMANDE for test on astra 19.2 (mhw)
5//channel C+ PORTADA for test on astra 19.2 (mhw2)
6//channel Sky Assist for test on hotbird (opentv)
7//channel EPG Background Audio for test on 28.2 (opentv)
8
9//global function
10
11struct freesat
12{
13        unsigned int value;
14        short bits;
15        char next;
16};
17
18typedef struct opentv
19{
20        char *value;
21        struct opentv *p0;
22        struct opentv *p1;
23} opentvnode;
24
25opentvnode opentvroot;
26static struct freesat *freesattable[2][128];
27static int freesattablesize[2][128];
28
29unsigned long getquad(void *ptr)
30{
31        unsigned char *data = ptr;
32        return (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];
33}
34
35unsigned short getdoub(void *ptr)
36{
37        unsigned char *data = ptr;
38        return (data[0] << 8) | data[1];
39}
40
41unsigned char resolvechar(char *str)
42{
43        int val = 0;
44
45        if(str == NULL) return '\0';
46
47        if(strcmp(str, "ESCAPE") == 0)
48                return '\1';
49        else if(strcmp(str, "STOP") == 0)
50                return '\0';
51        else if(strcmp(str, "START") == 0)
52                return '\0';
53        else if(sscanf(str, "0x%02x", &val) == 1)
54                return val;
55
56        return str[0];
57}
58
59unsigned long decodebinary(char *binary)
60{
61        unsigned long mask = 0x80000000;
62        unsigned long maskval = 0;
63        unsigned long val = 0;
64        size_t i = 0;
65
66        if(binary == NULL) return 0;
67
68        for(i = 0; i < strlen(binary); i++)
69        {
70                if(binary[i] == '1')
71                        val |= mask;
72                maskval |= mask;
73                mask >>= 1;
74        }
75        return val;
76}
77
78void freefreesat()
79{
80        int i = 0;
81
82        for(i = 0; i < 128; i++)
83        {
84                free(freesattable[0][i]);
85                freesattable[0][i] = NULL;
86        }
87
88        for(i = 0; i < 128; i++)
89        {
90                free(freesattable[1][i]);
91                freesattable[1][i] = NULL;
92        }
93}
94
95void freeopentvnode(opentvnode *node)
96{
97        if(node->p0 != NULL)
98        {
99                freeopentvnode(node->p0);
100                free(node->p0); node->p0 = NULL;
101        }
102
103        if(node->p1 != NULL)
104        {
105                freeopentvnode(node->p1);
106                free(node->p1); node->p1 = NULL;
107        }
108
109        free(node->value); node->value = NULL;
110}
111
112void freeopentv()
113{
114        freeopentvnode(&opentvroot);
115}
116
117int loadfreesat(int tableid, char *filename)
118{
119        char buf[1024];
120        char *from = NULL, *to = NULL, *binary = NULL;
121        FILE *fp = NULL;
122
123        tableid--;
124        if((fp = fopen(filename, "r")) != NULL)
125        {
126                debug(400, "loading table %d filename <%s>", tableid + 1, filename);
127
128                while(fgets(buf, sizeof(buf), fp) != NULL)
129                {
130                        from = binary = to = NULL;
131                        int elems = sscanf (buf, "%s[^:]:%s[^:]:%s[^:]:", from, binary, to);
132                        if(elems == 3)
133                        {
134                                int len = strlen(binary);
135                                int fromchar = resolvechar(from);
136                                char tochar = resolvechar(to);
137                                unsigned long bin = decodebinary(binary);
138                                int i = freesattablesize[tableid][fromchar]++;
139
140                                freesattable[tableid][fromchar] = (struct freesat*)realloc(freesattable[tableid][fromchar], (i + 1) * sizeof (freesattable[tableid][fromchar][0]));
141                                freesattable[tableid][fromchar][i].value = bin;
142                                freesattable[tableid][fromchar][i].next = tochar;
143                                freesattable[tableid][fromchar][i].bits = len;
144
145                                free (from); from = NULL;
146                                free (to); to = NULL;
147                                free (binary); binary = NULL;
148                        }
149                }
150                fclose(fp);
151        }
152        else
153        {
154                perr("cannot load <%s> for table %d", filename, tableid + 1);
155                return 1;
156        }
157        return 0;
158}
159
160//flag 0: SKY IT
161//flag 1: SKY UK
162int loadopentv(char *file)
163{
164        FILE *fd = NULL;
165        char line[512];
166        char value[256];
167        char code[256];
168        opentvnode *node;
169        int len = 0;
170        int count = 0;
171        int i = 0;
172
173        opentvroot.value = NULL;
174        opentvroot.p0 = NULL;
175        opentvroot.p1 = NULL;
176
177        fd = fopen(file, "r");
178        if(!fd)
179        {
180                perr("load %s", file);
181                return 1;
182        }
183
184        while(fgets(line, sizeof(line), fd))
185        {
186                memset(value, 0, sizeof(value));
187                memset(code, 0, sizeof(code));
188
189                if(sscanf(line, "%c=%[^\n]\n", value, code) != 2)
190                {
191                        if(sscanf(line, "%[^=]=%[^\n]\n", value, code) != 2)
192                        {
193                                if(sscanf(line, "=%[^\n]\n", code) != 1)
194                                        continue;
195                                else
196                                        memset(value, 0, sizeof (value));
197                        }
198                }
199
200                node = &opentvroot;
201                len = strlen(code);
202
203                for(i = 0; i < len; i++)
204                {
205                        switch(code[i])
206                        {
207                                case '0':
208                                        if(node->p0 == NULL)
209                                        {
210                                                node->p0 = malloc(sizeof(opentvnode));
211                                                node = node->p0;
212                                                node->value = NULL;
213                                                node->p0 = NULL;
214                                                node->p1 = NULL;
215                                                if(len == (i + 1))
216                                                {
217                                                        node->value = malloc(sizeof(char) * (strlen(value) + 1));
218                                                        sprintf(node->value, "%s", value);
219                                                        count++;
220                                                }
221                                        }
222                                        else
223                                        {
224                                                node = node->p0;
225                                                if((node->value != NULL) || (len == (i + 1)))
226                                                        err("huffman prefix code '%s' already exist", code);
227                                        }
228                                        break;
229
230                                case '1':
231                                        if(node->p1 == NULL)
232                                        {
233                                                node->p1 = malloc(sizeof(opentvnode));
234                                                node = node->p1;
235                                                node->value = NULL;
236                                                node->p0 = NULL;
237                                                node->p1 = NULL;
238                                                if(len == (i + 1))
239                                                {
240                                                        node->value = malloc(sizeof (char) * (strlen(value) + 1));
241                                                        sprintf(node->value, "%s", value);
242                                                        count++;
243                                                }
244                                        }
245                                        else
246                                        {
247                                                node = node->p1;
248                                                if((node->value != NULL) || (len == (i + 1)))
249                                                        err("huffman prefix code '%s' already exist", code);
250                                        }
251                                        break;
252                        }
253                }
254        }
255
256        fclose(fd);
257        return 0;
258}
259
260char *freesathuffmandecode(unsigned char *src, size_t size)
261{
262        int tableid = 0;
263
264        if(src == NULL) return NULL;
265
266        if(src[0] == 0x1f && (src[1] == 1 || src[1] == 2))
267        {
268                int uncompressedlen = 30, p = 0;
269                char *uncompressed = NULL;
270                unsigned value = 0, byte = 2, bit = 0;
271                unsigned char lastch = '\0';
272
273                uncompressed = calloc(1, uncompressedlen + 1);
274                if(uncompressed == NULL)
275                {
276                        err("no mem");
277                        return NULL;
278                }
279
280                tableid = src[1] - 1;
281                while(byte < 6 && byte < size)
282                {
283                        value |= src[byte] << ((5 - byte) * 8);
284                        byte++;
285                }
286
287                do
288                {
289                        int found = 0;
290                        unsigned bitshift = 0;
291                        if(lastch == '\1')
292                        {
293                                char nextchar = (value >> 24) & 0xff;
294                                found = 1;
295                                //Encoded in the next 8 bits.
296                                //Terminated by the first ASCII character.
297                                bitshift = 8;
298                                if((nextchar & 0x80) == 0)
299                                        lastch = nextchar;
300                                if(p >= uncompressedlen)
301                                {
302                                        uncompressedlen += 10;
303                                        uncompressed = (char *)realloc(uncompressed, uncompressedlen + 1);
304                                }
305                                uncompressed[p++] = nextchar;
306                                uncompressed[p] = '\0';
307                        }
308                        else
309                        {
310                                int j = 0;
311                                for(j = 0; j < freesattablesize[tableid][lastch]; j++)
312                                {
313                                        unsigned mask = 0, maskbit = 0x80000000;
314                                        short kk = 0;
315                                        for(kk = 0; kk < freesattable[tableid][lastch][j].bits; kk++)
316                                        {
317                                                mask |= maskbit;
318                                                maskbit >>= 1;
319                                        }
320                                        if((value & mask) == freesattable[tableid][lastch][j].value)
321                                        {
322                                                char nextchar = freesattable[tableid][lastch][j].next;
323                                                bitshift = freesattable[tableid][lastch][j].bits;
324                                                if(nextchar != '\0' && nextchar != '\1')
325                                                {
326                                                        if(p >= uncompressedlen)
327                                                        {
328                                                                uncompressedlen += 10;
329                                                                uncompressed = (char *)realloc(uncompressed, uncompressedlen + 1);
330                                                        }
331                                                        uncompressed[p++] = nextchar;
332                                                        uncompressed[p] = 0;
333                                                }
334                                                found = 1;
335                                                lastch = nextchar;
336                                                break;
337                                        }
338                                }
339                        }
340                        if(found)
341                        {
342                                //Shift up by the number of bits.
343                                unsigned b = 0;
344                                for(b = 0; b < bitshift; b++)
345                                {
346                                        value = (value << 1) & 0xfffffffe;
347                                        if(byte < size)
348                                                value |= (src[byte] >> (7 - bit)) & 1;
349                                        if(bit == 7)
350                                        {
351                                                bit = 0;
352                                                byte++;
353                                        }
354                                        else
355                                                bit++;
356                                }
357                        }
358                        else
359                        {
360                                debug(400, "missing table %d entry: <%s>", tableid + 1, uncompressed);
361                                //Entry missing in table.
362                                return uncompressed;
363                        }
364                } while(lastch != '\0' && value != 0);
365
366                return uncompressed;
367        }
368        return NULL;
369}
370
371//flag 0: SKY IT
372//flag 1: SKY UK
373int skyhuffmandecode(unsigned char *buf, int len, unsigned char *result, int resultmaxlen)
374{
375        opentvnode *node = &opentvroot;
376        unsigned char byte = 0;
377        unsigned char mask = 0;
378        int index = 0;
379        int toolong = 0;
380        int i = 0;
381
382        if(resultmaxlen > MINMALLOC) resultmaxlen = MINMALLOC;
383
384        for(i = 0; i < len; i++)
385        {
386                byte = buf[i];
387                if(i == 0) mask = 0x20;
388                else mask = 0x80;
389
390                do
391                {
392                        if((byte & mask) == 0)
393                        {
394                                if(node->p0 != NULL) node = node->p0;
395                                else
396                                {
397                                        err("cannot decode huffman data");
398                                        return 1;
399                                }
400                        }
401                        else
402                        {
403                                if (node->p1 != NULL) node = node->p1;
404                                else
405                                {
406                                        err("cannot decode huffman data");
407                                        return 1;
408                                }
409                        }
410
411                        if(node->value != NULL)
412                        {
413                                int size = 0;
414
415                                if((index + strlen(node->value)) >= (resultmaxlen - 1))
416                                {
417                                        size = resultmaxlen - len - 1;
418                                        toolong = 1;
419                                }
420                                else size = strlen(node->value);
421
422                                memcpy(result + index, node->value, size);
423                                index += size;
424                                node = &opentvroot;
425                        }
426
427                        if(toolong) break;
428
429                        mask = mask >> 1;
430                } while(mask > 0);
431
432                if(toolong == 1)
433                {
434                        debug(400, "huffman string is too long. truncated");
435                        break;
436                }
437        }
438
439        result[index] = '\0';
440
441        return 0;
442}
443
444struct extepgcache* addextepgcache(int id, struct epg* epgnode, struct extepgcache* last)
445{
446        struct extepgcache *newnode = NULL, *prev = NULL, *node = extepgcache;
447
448        newnode = (struct extepgcache*)calloc(1, sizeof(struct extepgcache));
449        if(newnode == NULL)
450        {
451                err("no memory");
452                return NULL;
453        }
454
455        newnode->id = id;
456        newnode->epgnode = epgnode;
457
458        if(last == NULL)
459        {
460                while(node != NULL)
461                {
462                        prev = node;
463                        node = node->next;
464                }
465        }
466        else
467        {
468                prev = last;
469                node = last->next;
470        }
471
472        if(prev == NULL)
473                extepgcache = newnode;
474        else
475                prev->next = newnode;
476        newnode->next = node;
477
478        return newnode;
479}
480
481void delextepgcache(struct extepgcache* cache)
482{
483        struct extepgcache *node = extepgcache, *prev = extepgcache;
484
485        while(node != NULL)
486        {
487                if(node == cache)
488                {
489                        if(node == extepgcache)
490                                extepgcache = node->next;
491                        else
492                                prev->next = node->next;
493
494                        free(node);
495                        node = NULL;
496                        break;
497                }
498
499                prev = node;
500                node = node->next;
501        }
502}
503
504void freeextepgcache()
505{
506        struct extepgcache *node = extepgcache, *prev = extepgcache;
507
508        while(node != NULL)
509        {
510                prev = node;
511                node = node->next;
512                if(prev != NULL)
513                        delextepgcache(prev);
514        }
515}
516
517struct extepgcache* getextepgcache(int id)
518{
519        struct extepgcache *node = extepgcache;
520
521        while(node != NULL)
522        {
523                if(node->id == id)
524                        return node;
525
526                node = node->next;
527        }
528        debug(100, "extepgcache not found (extepgcache=%d)", id);
529        return NULL;
530}
531
532struct extepgchannel* addextepgchannel(int id, int serviceid, off64_t transponderid, struct extepgchannel* last)
533{
534        struct extepgchannel *newnode = NULL, *prev = NULL, *node = extepgchannel;
535
536        newnode = (struct extepgchannel*)calloc(1, sizeof(struct extepgchannel));
537        if(newnode == NULL)
538        {
539                err("no memory");
540                return NULL;
541        }
542
543        newnode->id = id;
544        newnode->serviceid = serviceid;
545        newnode->transponderid = transponderid;
546
547        if(last == NULL)
548        {
549                while(node != NULL)
550                {
551                        prev = node;
552                        node = node->next;
553                }
554        }
555        else
556        {
557                prev = last;
558                node = last->next;
559        }
560
561        if(prev == NULL)
562                extepgchannel = newnode;
563        else
564                prev->next = newnode;
565        newnode->next = node;
566
567        return newnode;
568}
569
570void delextepgchannel(struct extepgchannel* channel)
571{
572        struct extepgchannel *node = extepgchannel, *prev = extepgchannel;
573
574        while(node != NULL)
575        {
576                if(node == channel)
577                {
578                        if(node == extepgchannel)
579                                extepgchannel = node->next;
580                        else
581                                prev->next = node->next;
582
583                        free(node);
584                        node = NULL;
585                        break;
586                }
587
588                prev = node;
589                node = node->next;
590        }
591}
592
593void freeextepgchannel()
594{
595        struct extepgchannel *node = extepgchannel, *prev = extepgchannel;
596
597        while(node != NULL)
598        {
599                prev = node;
600                node = node->next;
601                if(prev != NULL)
602                        delextepgchannel(prev);
603        }
604}
605
606struct extepgchannel* getextepgchannel(int id)
607{
608        struct extepgchannel *node = extepgchannel;
609
610        while(node != NULL)
611        {
612                if(node->id == id)
613                        return node;
614
615                node = node->next;
616        }
617        debug(100, "extepgchannel not found (extepgchannel=%d)", id);
618        return NULL;
619}
620
621struct extepgconfig* addextepgconfig(char *line, int count, struct extepgconfig* last)
622{
623        struct extepgconfig *newnode = NULL, *prev = NULL, *node = extepgconfig;
624        char *file = NULL;
625        int ret = 0;
626
627        if(line == NULL) return NULL;
628
629        newnode = (struct extepgconfig*)calloc(1, sizeof(struct extepgconfig));
630        if(newnode == NULL)
631        {
632                err("no memory");
633                return NULL;
634        }
635
636        file = malloc(MINMALLOC);
637        if(file == NULL)
638        {
639                err("no memory");
640                free(newnode);
641                return NULL;
642        }
643
644        ret = sscanf(line, "%llu#%d#%[^#]#%d#%d#%d#%d#%d#%d#%d#%d#%d#%d#%d#%d#%d#%d#%d#%d#%d", &newnode->transponderid, &newnode->type, file, &newnode->channelpid, \
645                &newnode->titlepid[0], &newnode->titlepid[1], &newnode->titlepid[2], &newnode->titlepid[3], \
646                &newnode->titlepid[4], &newnode->titlepid[5], &newnode->titlepid[6], &newnode->titlepid[7], \
647                &newnode->summarypid[0], &newnode->summarypid[1], &newnode->summarypid[2], &newnode->summarypid[3], \
648                &newnode->summarypid[4], &newnode->summarypid[5], &newnode->summarypid[6], &newnode->summarypid[7]);
649        if(ret != 20)
650        {
651                if(count > 0)
652                {
653                        err("extepgconfig line %d not ok or double", count);
654                }
655                else
656                {
657                        err("add extepgconfig");
658                }
659                free(file);
660                free(newnode);
661                return NULL;
662        }
663
664        newnode->file = ostrshrink(file);
665
666        if(last == NULL)
667        {
668                while(node != NULL)
669                {
670                        prev = node;
671                        node = node->next;
672                }
673        }
674        else
675        {
676                prev = last;
677                node = last->next;
678        }
679
680        if(prev == NULL)
681                extepgconfig = newnode;
682        else
683                prev->next = newnode;
684        newnode->next = node;
685
686        return newnode;
687}
688
689int readextepgconfig(char* filename)
690{
691        FILE *fd = NULL;
692        char *fileline = NULL;
693        int linecount = 0, len = 0;
694        struct extepgconfig* last = NULL, *tmplast = NULL;
695
696        fileline = malloc(MINMALLOC);
697        if(fileline == NULL)
698        {
699                err("no memory");
700                return 1;
701        }
702
703        fd = fopen(filename, "r");
704        if(fd == NULL)
705        {
706                perr("can't open %s", filename);
707                free(fileline);
708                return 1;
709        }
710
711        while(fgets(fileline, MINMALLOC, fd) != NULL)
712        {
713                if(fileline[0] == '#' || fileline[0] == '\n')
714                        continue;
715                len = strlen(fileline) - 1;
716                if(len >= 0 && fileline[len] == '\n')
717                        fileline[len] = '\0';
718                len--;
719                if(len >= 0 && fileline[len] == '\r')
720                        fileline[len] = '\0';
721
722                linecount++;
723
724                if(last == NULL) last = tmplast;
725                last = addextepgconfig(fileline, linecount, last);
726                if(last != NULL) tmplast = last;
727        }
728
729        free(fileline);
730        fclose(fd);
731        return 0;
732}
733
734void delextepgconfig(struct extepgconfig* config)
735{
736        struct extepgconfig *node = extepgconfig, *prev = extepgconfig;
737
738        while(node != NULL)
739        {
740                if(node == config)
741                {
742                        if(node == extepgconfig)
743                                extepgconfig = node->next;
744                        else
745                                prev->next = node->next;
746
747                        free(node->file);
748                        node->file = NULL;
749
750                        free(node);
751                        node = NULL;
752                        break;
753                }
754
755                prev = node;
756                node = node->next;
757        }
758}
759
760void freeextepgconfig()
761{
762        struct extepgconfig *node = extepgconfig, *prev = extepgconfig;
763
764        while(node != NULL)
765        {
766                prev = node;
767                node = node->next;
768                if(prev != NULL)
769                        delextepgconfig(prev);
770        }
771}
772
773struct extepgconfig* getextepgconfig(uint64_t transponderid, int type)
774{
775        struct extepgconfig *node = extepgconfig;
776
777        while(node != NULL)
778        {
779                if(node->transponderid == transponderid && node->type == type)
780                        return node;
781
782                node = node->next;
783        }
784        debug(100, "extepgconfig not found");
785        return NULL;
786}
787
788time_t localtime2utc(time_t t)
789{
790        struct tm *temp;
791
792        temp = gmtime(&t);
793        temp->tm_isdst = -1;
794        return mktime(temp);
795}
796
797time_t utc2localtime(time_t t)
798{
799        return 2 * t - localtime2utc(t);
800}
801
802int mhwtimeoffset(int *yesterday, time_t *yesterdayepoch)
803{
804        struct tm *curtime;
805        time_t yesterdaytime = 0;
806
807        // Get day of the week of yesterday (provider local time)
808        yesterdaytime = utc2localtime(time(NULL) - 86400);
809        curtime = gmtime(&yesterdaytime);
810        *yesterday = curtime->tm_wday;
811
812        // Get epoch of yesterday 00:00 (provider local time)
813        curtime->tm_hour = 0;
814        curtime->tm_min = 0;
815        curtime->tm_sec = 0;
816        curtime->tm_isdst = -1;
817        *yesterdayepoch = utc2localtime(mktime(curtime));
818
819        return 0;
820}
821
822//mhw
823struct mhwchannel* getmhwchannel(unsigned char* channelbuf, int channelcount, int id)
824{
825        struct mhwchannel* mhwchannel = NULL;
826        int i = 0;
827
828        if(channelbuf == NULL) return NULL;
829        mhwchannel = (struct mhwchannel*)(channelbuf + 4);
830
831        for(i = 0; i < channelcount; i++)
832        {
833                if(i == id - 1) return mhwchannel;
834                mhwchannel++;
835        }
836
837        return NULL;
838}
839
840int readmhwchannel(struct stimerthread* self, struct dvbdev* fenode, unsigned char* channelbuf, int pid)
841{
842        int readlen = 0;
843        struct dvbdev* dmxnode;
844
845        if(channelbuf == NULL) return -1;
846
847        if(fenode == NULL) fenode = status.aktservice->fedev;
848        if(fenode == NULL)
849        {
850                debug(400, "no frontend dev in service");
851                return -1;
852        }
853
854        dmxnode = dmxopen(fenode, 0);
855        if(dmxnode == NULL)
856        {
857                err("open demux dev");
858                return -1;
859        }
860
861        dmxsetbuffersize(dmxnode, getconfigint("dmxepgbuffersize", NULL));
862        dmxsetsource(dmxnode, fenode->fedmxsource);
863
864        dmxsetfilter(dmxnode, pid, 0, 16);
865
866        readlen = dvbread(dmxnode, channelbuf, 0, MINMALLOC, 2000000);
867        if(readlen <= 0)
868        {
869                dmxclose(dmxnode, -1);
870                return -1;
871        }
872
873        dmxclose(dmxnode, -1);
874        return readlen;
875}
876
877//flag 0 = from epg thread
878//flag 1 = from epg scan
879int readmhwtitle(struct stimerthread* self, struct dvbdev* fenode, struct channel* chnode, unsigned char* channelbuf, int channelcount, int pid, int flag)
880{
881        int readlen = 0, first = 1;
882        unsigned char *buf = NULL, *firstbuf = NULL;
883        struct dvbdev* dmxnode;
884        struct mhwtitle* mhwtitle = NULL;
885        struct mhwchannel* mhwchannel = NULL;
886        uint64_t transponderid = 0;
887        int serviceid = 0, eventid = 0, day = 0, hours = 0, yesterday = 0;
888        struct channel* tmpchnode = NULL;
889        struct epg* epgnode = NULL;
890        time_t dvbtime = 0, starttime = 0, endtime = 0, akttime = 0, yesterdayepoch = 0;
891        time_t epgmaxsec = status.epgdays * 24 * 60 * 60;
892        struct extepgcache* cache = NULL;
893
894        if(chnode == NULL) return 1;
895
896        mhwtimeoffset(&yesterday, &yesterdayepoch);
897
898        buf = calloc(1, MHWTITLELEN);
899        if(buf == NULL)
900        {
901                err("no memory");
902                return 1;
903        }
904        mhwtitle = (struct mhwtitle*)buf;
905
906        firstbuf = calloc(1, MHWTITLELEN);
907        if(firstbuf == NULL)
908        {
909                err("no memory");
910                free(buf);
911                return 1;
912        }
913
914        if(fenode == NULL) fenode = status.aktservice->fedev;
915        if(fenode == NULL)
916        {
917                debug(400, "no frontend dev in service");
918                free(buf);
919                free(firstbuf);
920                return 1;
921        }
922
923        dmxnode = dmxopen(fenode, 0);
924        if(dmxnode == NULL)
925        {
926                err("open demux dev");
927                free(buf);
928                free(firstbuf);
929                return 1;
930        }
931
932        dmxsetbuffersize(dmxnode, getconfigint("dmxepgbuffersize", NULL));
933        dmxsetsource(dmxnode, fenode->fedmxsource);
934
935        dmxsetfilter(dmxnode, pid, 0, 15);
936        akttime = time(NULL);
937
938        while(self->aktion != STOP && self->aktion != PAUSE)
939        {
940                readlen = dvbread(dmxnode, buf, 0, MHWTITLELEN, 2000000);
941                usleep(1000);
942                if(readlen != MHWTITLELEN)
943                {
944                        perr("while reading titles");
945                        dmxclose(dmxnode, -1);
946                        free(buf);
947                        free(firstbuf);
948                        return 1;
949                }
950                if(first == 1)
951                {
952                        first = 0;
953                        memcpy(firstbuf, buf, MHWTITLELEN);
954                }
955                else
956                {
957                        if(memcmp(firstbuf, buf, MHWTITLELEN) == 0)
958                        {
959                                debug(400, "mhwepg no more new data, wait for next run");
960
961                                if(chnode != NULL && chnode->transponder != NULL)
962                                        chnode->transponder->lastepg = time(NULL) + 7700;
963                                break;
964                        }
965
966                        //stop epgscan after 2 min
967                        if(akttime + 120 < time(NULL))
968                        {
969                                debug(400, "mhwepg timeout");
970                                break;
971                        }
972                }
973
974                mhwchannel = getmhwchannel(channelbuf, channelcount, mhwtitle->channel_id);
975                if(mhwchannel != NULL)
976                {
977                        transponderid = ((HILO(mhwchannel->network_id) << 16) | HILO(mhwchannel->transponder_id)) & 0xffffffff;
978                        if(chnode->transponder != NULL)
979                        {
980                                if(chnode->transponder->fetype == FE_QAM)
981                                        transponderid = transponderid | ((uint64_t)1 << 32);
982                                else if(chnode->transponder->fetype == FE_OFDM)
983                                        transponderid = transponderid | ((uint64_t)2 << 32);
984                        }
985
986                        serviceid = HILO(mhwchannel->channel_id);
987                        tmpchnode = getchannel(serviceid, transponderid);
988                        if(tmpchnode == NULL)
989                                continue;
990
991                        //look in epglist if channel exists
992                        //only if epglist is marked as whitelist
993                        if(status.epglistmode == 2 || status.epglistmode == 3)
994                        {
995                                if(getepgscanlist(serviceid, transponderid) == NULL)
996                                        continue;
997                        }
998
999                        m_lock(&status.epgmutex, 4);
1000
1001                        eventid = (mhwtitle->channel_id << 16) | (mhwtitle->day << 13) | (mhwtitle->hours << 8) | mhwtitle->minutes;
1002                        epgnode = getepg(tmpchnode, eventid, 1);
1003
1004                        //get start/endtime
1005                        day = mhwtitle->day;
1006                        hours = mhwtitle->hours;
1007                        if(day == 7) day = 0;
1008                        if(hours > 15) hours = hours - 4;
1009                        else if(hours > 7) hours = hours - 2;
1010                        else day = (day == 6) ? 0 : day + 1;
1011
1012                        dvbtime = (day - yesterday) * 86400 + hours * 3600 + mhwtitle->minutes * 60;
1013                        if(dvbtime < 6 * 3600) dvbtime += 7 * 86400;    /* Next week */
1014                        dvbtime += yesterdayepoch;
1015                        starttime = localtime2utc(dvbtime);
1016                        endtime = starttime + (HILO(mhwtitle->duration) * 60);
1017
1018#ifndef SIMULATE
1019                        if(endtime < time(NULL) || starttime > time(NULL) + epgmaxsec)
1020                        {
1021                                m_unlock(&status.epgmutex, 4);
1022                                continue;
1023                        }
1024#endif
1025
1026                        if(epgnode == NULL)
1027                                epgnode = addepg(tmpchnode, eventid, 0, starttime, endtime, NULL, 1);
1028                        else
1029                                updateepg(tmpchnode, epgnode, eventid, 0, starttime, endtime, 1);
1030
1031                        if(epgnode == NULL)
1032                        {
1033                                m_unlock(&status.epgmutex, 4);
1034                                continue;
1035                        }
1036
1037                        epgnode->title = ostrcat((char*)mhwtitle->title, NULL, 0, 0);
1038                        epgnode->title = strstrip(epgnode->title);
1039                        cache = addextepgcache(HILO32(mhwtitle->program_id), epgnode, cache);
1040
1041                        m_unlock(&status.epgmutex, 4);
1042                }
1043        }
1044
1045        dmxclose(dmxnode, -1);
1046        free(buf);
1047        free(firstbuf);
1048        return 0;
1049}
1050
1051int readmhwsummary(struct stimerthread* self, struct dvbdev* fenode, int pid)
1052{
1053        int readlen = 0, first = 1, len = 0;
1054        unsigned char *buf = NULL, *firstbuf = NULL;
1055        struct dvbdev* dmxnode;
1056        time_t akttime = 0;
1057        char* tmpstr = NULL;
1058        struct mhwsummary* mhwsummary = NULL;
1059        char* zbuf = NULL;
1060        int zlen = 0, ret = 0;
1061        struct extepgcache* cache = NULL;
1062
1063        buf = calloc(1, MINMALLOC);
1064        if(buf == NULL)
1065        {
1066                err("no memory");
1067                return 1;
1068        }
1069        mhwsummary = (struct mhwsummary*)buf;
1070
1071        firstbuf = calloc(1, MINMALLOC);
1072        if(firstbuf == NULL)
1073        {
1074                err("no memory");
1075                free(buf);
1076                return 1;
1077        }
1078
1079        if(fenode == NULL) fenode = status.aktservice->fedev;
1080        if(fenode == NULL)
1081        {
1082                debug(400, "no frontend dev in service");
1083                free(buf);
1084                free(firstbuf);
1085                return 1;
1086        }
1087
1088        dmxnode = dmxopen(fenode, 0);
1089        if(dmxnode == NULL)
1090        {
1091                err("open demux dev");
1092                free(buf);
1093                free(firstbuf);
1094                return 1;
1095        }
1096
1097        dmxsetbuffersize(dmxnode, getconfigint("dmxepgbuffersize", NULL));
1098        dmxsetsource(dmxnode, fenode->fedmxsource);
1099
1100        dmxsetfilter(dmxnode, pid, 0, 17);
1101        akttime = time(NULL);
1102
1103        while(self->aktion != STOP && self->aktion != PAUSE)
1104        {
1105                readlen = dvbread(dmxnode, buf, 0, 3, 2000000);
1106                if(readlen != 3)
1107                {
1108                        dmxclose(dmxnode, -1);
1109                        free(buf);
1110                        free(firstbuf);
1111                        return 1;
1112                }
1113                readlen = 0;
1114                len = buf[2] | ((buf[1] & 0x0f) << 8);
1115                if(len + 3 <= MINMALLOC)
1116                        readlen = dvbread(dmxnode, buf, 3, len, 2000000);
1117                if(readlen <= 0)
1118                {
1119                        dmxclose(dmxnode, -1);
1120                        free(buf);
1121                        free(firstbuf);
1122                        return 1;
1123                }
1124
1125                //stop epgscan after 2 min
1126                if(akttime + 120 < time(NULL))
1127                {
1128                        debug(400, "mhwepg timeout");
1129                        break;
1130                }
1131
1132                // Invalid Data
1133                if(readlen < 12 || buf[7] != 0xFF || buf[8] != 0xFF || buf[9] !=0xFF || buf[10] >= 10)
1134                        continue;
1135
1136                if(first == 1)
1137                {
1138                        first = 0;
1139                        memcpy(firstbuf, buf, readlen + 3);
1140                }
1141                else
1142                {
1143                        if(memcmp(firstbuf, buf, readlen + 3) == 0)
1144                        {
1145                                debug(400, "mhwsummary no more new data, wait for next run");
1146                                break;
1147                        }
1148                }
1149
1150                buf[readlen + 3] = '\0'; //String terminator
1151
1152                cache = getextepgcache(HILO32(mhwsummary->program_id));
1153                if(cache != NULL && cache->epgnode != NULL)
1154                {
1155
1156                        //Index of summary text beginning
1157                        tmpstr = (char*)(buf + MHWSUMMARYLEN + mhwsummary->nb_replays * 7);
1158                        tmpstr = stringreplacechar(tmpstr, '\n', ' ');
1159
1160                        //compress long desc
1161                        if(tmpstr != NULL)
1162                        {
1163                                ret = ozip(tmpstr, strlen(tmpstr) + 1, &zbuf, &zlen, 1);
1164                                if(ret == 0)
1165                                {
1166                                        free(cache->epgnode->desc); cache->epgnode->desc = NULL;
1167                                        cache->epgnode->desc = zbuf;
1168                                        cache->epgnode->desccomplen = zlen;
1169                                }
1170                        }
1171                        tmpstr = NULL;
1172                }
1173        }
1174
1175        dmxclose(dmxnode, -1);
1176        free(buf);
1177        free(firstbuf);
1178        return 0;
1179}
1180
1181//flag 0 = from epg thread
1182//flag 1 = from epg scan
1183int readmhw(struct stimerthread* self, struct channel* chnode, struct dvbdev* fenode, int flag)
1184{
1185        int ret = 0, channelcount = 0, i = 0;
1186        unsigned char* channelbuf = NULL;
1187        struct extepgconfig* extepgconfignode = NULL;
1188
1189        if(self == NULL) return 1;
1190
1191        if(chnode == NULL) chnode = status.aktservice->channel;
1192        if(chnode == NULL || (flag == 0 && chnode == status.aktservice->channel && status.aktservice->type != CHANNEL))
1193                return 1;
1194
1195        extepgconfignode = getextepgconfig(chnode->transponderid, 0);
1196        if(extepgconfignode == NULL) extepgconfignode = getextepgconfig(0, 0);
1197        if(extepgconfignode == NULL)
1198        {
1199                debug(400, "transponder not found in extepgconfig");
1200                return 1;
1201        }
1202
1203        if(fenode == NULL) fenode = status.aktservice->fedev;
1204        if(fenode == NULL)
1205        {
1206                debug(400, "no frontend dev in service");
1207                return 1;
1208        }
1209
1210        channelbuf = calloc(1, MINMALLOC);
1211        if(channelbuf == NULL)
1212        {
1213                err("no memory");
1214                return 1;
1215        }
1216
1217        channelcount = readmhwchannel(self, fenode, channelbuf, extepgconfignode->channelpid);
1218        if(channelcount <= 0 || self->aktion == STOP || self->aktion == PAUSE)
1219        {
1220                debug(400, "mhwepg no channels found");
1221                ret = 1;
1222                goto end;
1223        }
1224
1225        ret = 1;
1226        for(i = 0; i < 8; i++)
1227        {
1228                if(extepgconfignode->titlepid[i] < 0) continue;
1229                if(self->aktion == STOP || self->aktion == PAUSE) break;
1230                int tmpret = readmhwtitle(self, fenode, chnode, channelbuf, channelcount, extepgconfignode->titlepid[i], flag);
1231                if(tmpret == 0) ret = 0;
1232        }
1233        if(ret != 0 || self->aktion == STOP || self->aktion == PAUSE)
1234        {
1235                debug(400, "mhwepg no titles found");
1236                ret = 1;
1237                goto end;
1238        }
1239
1240        ret = 1;
1241        for(i = 0; i < 8; i++)
1242        {
1243                if(extepgconfignode->summarypid[i] < 0) continue;
1244                if(self->aktion == STOP || self->aktion == PAUSE) break;
1245                int tmpret = readmhwsummary(self, fenode, extepgconfignode->summarypid[i]);
1246                if(tmpret == 0) ret = 0;
1247        }
1248        if(ret != 0 || self->aktion == STOP || self->aktion == PAUSE)
1249        {
1250                debug(400, "mhwepg no summary found");
1251                ret = 1;
1252                goto end;
1253        }
1254
1255        ret = 0;
1256
1257end:
1258
1259        free(channelbuf); channelbuf = NULL;
1260        freeextepgcache();
1261        return ret;
1262}
1263
1264//mhw2
1265struct mhw2channel* getmhw2channel(unsigned char* channelbuf, int id)
1266{
1267        struct mhw2channel* mhw2channel = NULL;
1268        int channelcount = 0;
1269        int i = 0;
1270
1271        if(channelbuf == NULL) return NULL;
1272        mhw2channel = (struct mhw2channel*)(channelbuf + 121);
1273
1274        channelcount = channelbuf[120];
1275
1276        for(i = 0; i < channelcount; i++)
1277        {
1278                if(i == id - 1) return mhw2channel;
1279                mhw2channel++;
1280        }
1281
1282        return NULL;
1283}
1284
1285int readmhw2channel(struct stimerthread* self, struct dvbdev* fenode, unsigned char* channelbuf, int pid)
1286{
1287        int readlen = 0, count = 0;
1288        unsigned short len = 0;
1289        struct dvbdev* dmxnode;
1290
1291        if(channelbuf == NULL) return 1;
1292
1293        if(fenode == NULL) fenode = status.aktservice->fedev;
1294        if(fenode == NULL)
1295        {
1296                debug(400, "no frontend dev in service");
1297                return 1;
1298        }
1299
1300        dmxnode = dmxopen(fenode, 0);
1301        if(dmxnode == NULL)
1302        {
1303                err("open demux dev");
1304                return 1;
1305        }
1306
1307        dmxsetbuffersize(dmxnode, getconfigint("dmxepgbuffersize", NULL));
1308        dmxsetsource(dmxnode, fenode->fedmxsource);
1309
1310        dmxsetfilter(dmxnode, pid, 0, 19);
1311
1312start:
1313        readlen = dvbread(dmxnode, channelbuf, 0, 3, 2000000);
1314        if(readlen != 3)
1315        {
1316                dmxclose(dmxnode, -1);
1317                return 1;
1318        }
1319        readlen = 0;
1320        len = channelbuf[2] | ((channelbuf[1] & 0x0f) << 8);
1321        if(len + 3 <= MINMALLOC)
1322                readlen = dvbread(dmxnode, channelbuf, 3, len, 2000000);
1323        if(readlen <= 0)
1324        {
1325                dmxclose(dmxnode, -1);
1326                return 1;
1327        }
1328
1329        count++;
1330        if(channelbuf[3] != 0 && count < 6) goto start;
1331
1332        dmxclose(dmxnode, -1);
1333
1334        if(count >= 6)
1335                return 1;
1336        else
1337                return 0;
1338}
1339
1340//flag 0 = from epg thread
1341//flag 1 = from epg scan
1342int readmhw2title(struct stimerthread* self, struct dvbdev* fenode, struct channel* chnode, unsigned char* channelbuf, int pid, int flag)
1343{
1344        int readlen = 0, pos = 0, len = 0;
1345        unsigned char *buf = NULL;
1346        struct dvbdev* dmxnode;
1347        struct mhw2channel* mhw2channel = NULL;
1348        uint64_t transponderid = 0;
1349        int serviceid = 0, eventid = 0;
1350        struct channel* tmpchnode = NULL;
1351        unsigned long quad = 0, quad0 = 0;
1352        struct epg* epgnode = NULL;
1353        time_t dvbtime = 0, starttime = 0, endtime = 0, akttime = 0;
1354        time_t epgmaxsec = status.epgdays * 24 * 60 * 60;
1355        char tmpstr[65];
1356        struct extepgcache* cache = NULL;
1357
1358        if(chnode == NULL) return 1;
1359
1360        buf = calloc(1, MINMALLOC);
1361        if(buf == NULL)
1362        {
1363                err("no memory");
1364                return 1;
1365        }
1366
1367        if(fenode == NULL) fenode = status.aktservice->fedev;
1368        if(fenode == NULL)
1369        {
1370                debug(400, "no frontend dev in service");
1371                free(buf);
1372                return 1;
1373        }
1374
1375        dmxnode = dmxopen(fenode, 0);
1376        if(dmxnode == NULL)
1377        {
1378                err("open demux dev");
1379                free(buf);
1380                return 1;
1381        }
1382
1383        dmxsetbuffersize(dmxnode, getconfigint("dmxepgbuffersize", NULL));
1384        dmxsetsource(dmxnode, fenode->fedmxsource);
1385
1386        dmxsetfilter(dmxnode, pid, 0, 18);
1387        akttime = time(NULL);
1388
1389        while(self->aktion != STOP && self->aktion != PAUSE)
1390        {
1391                readlen = dvbread(dmxnode, buf, 0, 3, 2000000);
1392                if(readlen != 3)
1393                {
1394                        dmxclose(dmxnode, -1);
1395                        free(buf);
1396                        return 1;
1397                }
1398                readlen = 0;
1399                len = buf[2] | ((buf[1] & 0x0f) << 8);
1400                if(len + 3 <= MINMALLOC)
1401                        readlen = dvbread(dmxnode, buf, 3, len, 2000000);
1402                if(readlen <= 0)
1403                {
1404                        dmxclose(dmxnode, -1);
1405                        free(buf);
1406                        return 1;
1407                }
1408
1409                //check for end
1410                quad = getquad(buf + 3);
1411                if(quad0 == 0) quad0 = quad;
1412                else if(quad == quad0)
1413                {
1414                        debug(400, "mhw2epg no more new data, wait for next run");
1415
1416                        if(chnode != NULL && chnode->transponder != NULL)
1417                                chnode->transponder->lastepg = time(NULL) + 7700;
1418                        break;
1419                }
1420
1421                //stop epgscan after 2 min
1422                if(akttime + 120 < time(NULL))
1423                {
1424                        debug(400, "mhw2epg timeout");
1425                        break;
1426                }
1427
1428                pos = 18;
1429                while(pos < len)
1430                {
1431                        int channelid = buf[pos];
1432                        eventid = (buf[pos + 7] << 24) | (buf[pos + 8] << 16) | (buf[pos + 9] << 8) | buf[pos + 10];
1433
1434                        //get start/endtime
1435                        pos += 11;
1436                        dvbtime = (getdoub(buf + pos) - 40587) * 86400
1437                         + (((buf[pos + 2] & 0xf0) >> 4) * 10 + (buf[pos + 2] & 0x0f)) * 3600
1438                         + (((buf[pos + 3] & 0xf0) >> 4) * 10 + (buf[pos + 3] & 0x0f)) * 60;
1439
1440                        starttime = dvbtime;
1441                        endtime = starttime + (getdoub(buf + pos + 5) >> 4) * 60;
1442
1443                        int lgr = buf[pos + 7] & 0x3f;
1444                        if(lgr < 65)
1445                        {
1446                                memcpy(tmpstr, buf + pos + 8, lgr);
1447                                tmpstr[lgr] = '\0';
1448                        }
1449                        else
1450                                tmpstr[0] = '\0';
1451                        pos += lgr + 8;
1452                        int progid = getdoub(buf + pos + 1);
1453
1454                        mhw2channel = getmhw2channel(channelbuf, channelid);
1455                        if(mhw2channel != NULL)
1456                        {
1457                                transponderid = ((HILO(mhw2channel->network_id) << 16) | HILO(mhw2channel->transponder_id)) & 0xffffffff;
1458                                if(chnode->transponder != NULL)
1459                                {
1460                                        if(chnode->transponder->fetype == FE_QAM)
1461                                                transponderid = transponderid | ((uint64_t)1 << 32);
1462                                        else if(chnode->transponder->fetype == FE_OFDM)
1463                                                transponderid = transponderid | ((uint64_t)2 << 32);
1464                                }
1465
1466                                serviceid = HILO(mhw2channel->channel_id);
1467                                tmpchnode = getchannel(serviceid, transponderid);
1468                                if(tmpchnode == NULL)
1469                                {
1470                                        pos += 3;
1471                                        continue;
1472                                }
1473
1474                                //look in epglist if channel exists
1475                                //only if epglist is marked as whitelist
1476                                if(status.epglistmode == 2 || status.epglistmode == 3)
1477                                {
1478                                        if(getepgscanlist(serviceid, transponderid) == NULL)
1479                                        {
1480                                                pos += 3;
1481                                                continue;
1482                                        }
1483                                }
1484
1485                                m_lock(&status.epgmutex, 4);
1486
1487                                epgnode = getepg(tmpchnode, eventid, 1);
1488
1489#ifndef SIMULATE
1490                                if(endtime < time(NULL) || starttime > time(NULL) + epgmaxsec)
1491                                {
1492                                        m_unlock(&status.epgmutex, 4);
1493                                        pos += 3;
1494                                        continue;
1495                                }
1496#endif
1497
1498                                if(epgnode == NULL)
1499                                        epgnode = addepg(tmpchnode, eventid, 0, starttime, endtime, NULL, 1);
1500                                else
1501                                        updateepg(tmpchnode, epgnode, eventid, 0, starttime, endtime, 1);
1502
1503                                if(epgnode == NULL)
1504                                {
1505                                        m_unlock(&status.epgmutex, 4);
1506                                        pos += 3;
1507                                        continue;
1508                                }
1509
1510                                epgnode->title = ostrcat(tmpstr, NULL, 0, 0);
1511                                cache = addextepgcache(progid, epgnode, cache);
1512
1513                                m_unlock(&status.epgmutex, 4);
1514
1515                        }
1516                        pos += 3;
1517                }
1518        }
1519
1520        dmxclose(dmxnode, -1);
1521        free(buf);
1522        return 0;
1523}
1524
1525int readmhw2summary(struct stimerthread* self, struct dvbdev* fenode, int pid)
1526{
1527        int readlen = 0, len = 0, first = 1;
1528        unsigned char *buf = NULL, *firstbuf = NULL;
1529        struct dvbdev* dmxnode;
1530        time_t akttime = 0;
1531        char* zbuf = NULL;
1532        int zlen = 0, ret = 0;
1533        char tmpstr[MINMALLOC];
1534        struct extepgcache* cache = NULL;
1535
1536        buf = calloc(1, MINMALLOC);
1537        if(buf == NULL)
1538        {
1539                err("no memory");
1540                return 1;
1541        }
1542
1543        firstbuf = calloc(1, MINMALLOC);
1544        if(firstbuf == NULL)
1545        {
1546                err("no memory");
1547                free(buf);
1548                return 1;
1549        }
1550
1551        if(fenode == NULL) fenode = status.aktservice->fedev;
1552        if(fenode == NULL)
1553        {
1554                debug(400, "no frontend dev in service");
1555                free(buf);
1556                free(firstbuf);
1557                return 1;
1558        }
1559
1560        dmxnode = dmxopen(fenode, 0);
1561        if(dmxnode == NULL)
1562        {
1563                err("open demux dev");
1564                free(buf);
1565                free(firstbuf);
1566                return 1;
1567        }
1568
1569        dmxsetbuffersize(dmxnode, getconfigint("dmxepgbuffersize", NULL));
1570        dmxsetsource(dmxnode, fenode->fedmxsource);
1571
1572        dmxsetfilter(dmxnode, pid, 0, 20);
1573        akttime = time(NULL);
1574
1575        while(self->aktion != STOP && self->aktion != PAUSE)
1576        {
1577                tmpstr[0] = '\0';
1578
1579                readlen = dvbread(dmxnode, buf, 0, 3, 2000000);
1580                if(readlen != 3)
1581                {
1582                        dmxclose(dmxnode, -1);
1583                        free(buf);
1584                        free(firstbuf);
1585                        return 1;
1586                }
1587                readlen = 0;
1588                len = buf[2] | ((buf[1] & 0x0f) << 8);
1589                if(len + 3 <= MINMALLOC)
1590                        readlen = dvbread(dmxnode, buf, 3, len, 2000000);
1591                if(readlen <= 0)
1592                {
1593                        dmxclose(dmxnode, -1);
1594                        free(buf);
1595                        free(firstbuf);
1596                        return 1;
1597                }
1598
1599                //check for end
1600                if(first == 1)
1601                {
1602                        first = 0;
1603                        memcpy(firstbuf, buf, readlen + 3);
1604                }
1605                else
1606                {
1607                        if(memcmp(firstbuf, buf, readlen + 3) == 0)
1608                        {
1609                                debug(400, "mhw2epg no more new data, wait for next run");
1610                                break;
1611                        }
1612
1613                        //stop epgscan after 2 min
1614                        if(akttime + 120 < time(NULL))
1615                        {
1616                                debug(400, "mhw2epg timeout");
1617                                break;
1618                        }
1619                }
1620
1621                int textlen = buf[14];
1622                int sumlen = textlen;
1623                int pos = 15;
1624                int loop = buf[pos + sumlen] & 0x0f;
1625                int progid = (buf[3] << 8) | buf[4];
1626
1627                memcpy(tmpstr, (char*)&buf[pos], textlen);
1628                tmpstr[sumlen] = ' ';
1629
1630                sumlen++;
1631                pos += (textlen + 1);
1632                if(loop > 0)
1633                {
1634                        while(loop > 0)
1635                        {
1636                                textlen = buf[pos];
1637                                pos += 1;
1638                                if(pos + textlen < readlen + 3)
1639                                {
1640                                        memcpy(&tmpstr[sumlen], (char*)&buf[pos], textlen);
1641                                        sumlen += textlen;
1642                                        if(loop > 1)
1643                                        {
1644                                                tmpstr[sumlen] = ' ';
1645                                                sumlen++;
1646                                        }
1647                                }
1648                                else
1649                                        break;
1650
1651                                pos += textlen;
1652                                loop--;
1653                        }
1654                }
1655                tmpstr[sumlen] = '\0';
1656
1657                cache = getextepgcache(progid);
1658                if(cache != NULL && cache->epgnode != NULL)
1659                {
1660                        //tmpstr = stringreplacechar(tmpstr, '\n', ' ');
1661
1662                        //compress long desc
1663                        if(tmpstr[0] != '\0')
1664                        {
1665                                ret = ozip(tmpstr, strlen(tmpstr) + 1, &zbuf, &zlen, 1);
1666                                if(ret == 0)
1667                                {
1668                                        free(cache->epgnode->desc); cache->epgnode->desc = NULL;
1669                                        cache->epgnode->desc = zbuf;
1670                                        cache->epgnode->desccomplen = zlen;
1671                                }
1672                        }
1673                }
1674        }
1675
1676        dmxclose(dmxnode, -1);
1677        free(buf);
1678        free(firstbuf);
1679        return 0;
1680}
1681
1682//flag 0 = from epg thread
1683//flag 1 = from epg scan
1684int readmhw2(struct stimerthread* self, struct channel* chnode, struct dvbdev* fenode, int flag)
1685{
1686        int ret = 0, i = 0;
1687        unsigned char* channelbuf = NULL;
1688        struct extepgconfig* extepgconfignode = NULL;
1689
1690        if(self == NULL) return 1;
1691
1692        if(chnode == NULL) chnode = status.aktservice->channel;
1693        if(chnode == NULL || (flag == 0 && chnode == status.aktservice->channel && status.aktservice->type != CHANNEL))
1694                return 1;
1695
1696        extepgconfignode = getextepgconfig(chnode->transponderid, 1);
1697        if(extepgconfignode == NULL) extepgconfignode = getextepgconfig(0, 1);
1698        if(extepgconfignode == NULL)
1699        {
1700                debug(400, "transponder not found in extepgconfig");
1701                return 1;
1702        }
1703
1704        if(fenode == NULL) fenode = status.aktservice->fedev;
1705        if(fenode == NULL)
1706        {
1707                debug(400, "no frontend dev in service");
1708                return 1;
1709        }
1710
1711        channelbuf = calloc(1, MINMALLOC);
1712        if(channelbuf == NULL)
1713        {
1714                err("no memory");
1715                return 1;
1716        }
1717
1718        ret = readmhw2channel(self, fenode, channelbuf, extepgconfignode->channelpid);
1719        if(ret != 0 || self->aktion == STOP || self->aktion == PAUSE)
1720        {
1721                debug(400, "mhw2epg no channel found");
1722                ret = 1;
1723                goto end;
1724        }
1725
1726        ret = 1;
1727        for(i = 0; i < 8; i++)
1728        {
1729                if(extepgconfignode->titlepid[i] < 0) continue;
1730                if(self->aktion == STOP || self->aktion == PAUSE) break;
1731                int tmpret = readmhw2title(self, fenode, chnode, channelbuf, extepgconfignode->titlepid[i], flag);
1732                if(tmpret == 0) ret = 0;
1733        }
1734        if(ret != 0 || self->aktion == STOP || self->aktion == PAUSE)
1735        {
1736                debug(400, "mhw2epg no titles found");
1737                ret = 1;
1738                goto end;
1739        }
1740
1741        ret = 1;
1742        for(i = 0; i < 8; i++)
1743        {
1744                if(extepgconfignode->summarypid[i] < 0) continue;
1745                if(self->aktion == STOP || self->aktion == PAUSE) break;
1746                int tmpret = readmhw2summary(self, fenode, extepgconfignode->summarypid[i]);
1747                if(tmpret == 0) ret = 0;
1748        }
1749        if(ret != 0 || self->aktion == STOP || self->aktion == PAUSE)
1750        {
1751                debug(400, "mhw2epg no summary found");
1752                ret = 1;
1753                goto end;
1754        }
1755
1756        ret = 0;
1757
1758end:
1759
1760        free(channelbuf); channelbuf = NULL;
1761        freeextepgcache();
1762        return 0;
1763}
1764
1765//opentv
1766//flag 0 = from epg thread
1767//flag 1 = from epg scan
1768int createopentvchannel(unsigned char* channelbuf, struct channel* chnode, int flag)
1769{
1770        if(channelbuf == NULL) return 1;
1771
1772        if(chnode == NULL) return 1;
1773
1774        int bouquetdesclen = ((channelbuf[8] & 0x0f) << 8) | channelbuf[9];
1775        int looplen = ((channelbuf[bouquetdesclen + 10] & 0x0f) << 8) | channelbuf[bouquetdesclen + 11];
1776        int p1 = bouquetdesclen + 12;
1777
1778        while(looplen > 0)
1779        {
1780                unsigned short int tid = (channelbuf[p1] << 8) | channelbuf[p1 + 1];
1781                unsigned short int nid = (channelbuf[p1 + 2] << 8) | channelbuf[p1 + 3];
1782                int transpdesclen = ((channelbuf[p1 + 4] & 0x0f) << 8) | channelbuf[p1 + 5];
1783                int p2 = p1 + 6;
1784
1785                p1 += transpdesclen + 6;
1786                looplen -= (transpdesclen + 6);
1787                while(transpdesclen > 0)
1788                {
1789                        unsigned char desctag = channelbuf[p2];
1790                        int desclen = channelbuf[p2 + 1];
1791                        int p3 = p2 + 2;
1792
1793                        p2 += desclen + 2;
1794                        transpdesclen -= (desclen + 2);
1795                        if(desctag == 0xb1)
1796                        {
1797                                p3 += 2;
1798                                desclen -= 2;
1799                                while(desclen > 0)
1800                                {
1801                                        unsigned short int sid = (channelbuf[p3] << 8) | channelbuf[p3 + 1];
1802                                        unsigned short int channelid = (channelbuf[p3 + 3] << 8) | channelbuf[p3 + 4];
1803                                        if(getextepgchannel(channelid) == NULL)
1804                                        {
1805                                                uint64_t transponderid = ((nid << 16) | tid) & 0xffffffff;
1806                                                if(chnode->transponder != NULL)
1807                                                {
1808                                                        if(chnode->transponder->fetype == FE_QAM)
1809                                                                transponderid = transponderid | ((uint64_t)1 << 32);
1810                                                        else if(chnode->transponder->fetype == FE_OFDM)
1811                                                                transponderid = transponderid | ((uint64_t)2 << 32);
1812                                                }
1813                                                addextepgchannel(channelid, sid, transponderid, NULL);
1814                                        }
1815                                        p3 += 9;
1816                                        desclen -= 9;
1817                                }
1818                        }
1819                }
1820        }
1821
1822        return 0;
1823}
1824
1825//flag 0 = from epg thread
1826//flag 1 = from epg scan
1827int readopentvchannel(struct stimerthread* self, struct dvbdev* fenode, struct channel* chnode, unsigned char* channelbuf, int pid, int flag)
1828{
1829        int readlen = 0, first = 1;
1830        unsigned short len = 0;
1831        struct dvbdev* dmxnode;
1832        char* firstbuf = NULL;
1833        time_t akttime = 0;
1834
1835        if(channelbuf == NULL) return 1;
1836
1837        if(chnode == NULL) return 1;
1838
1839        firstbuf = calloc(1, MINMALLOC);
1840        if(firstbuf == NULL)
1841        {
1842                err("no memory");
1843                return 1;
1844        }
1845
1846        if(fenode == NULL) fenode = status.aktservice->fedev;
1847        if(fenode == NULL)
1848        {
1849                debug(400, "no frontend dev in service");
1850                free(firstbuf);
1851                return 1;
1852        }
1853
1854        dmxnode = dmxopen(fenode, 0);
1855        if(dmxnode == NULL)
1856        {
1857                err("open demux dev");
1858                free(firstbuf);
1859                return 1;
1860        }
1861
1862        dmxsetbuffersize(dmxnode, getconfigint("dmxepgbuffersize", NULL));
1863        dmxsetsource(dmxnode, fenode->fedmxsource);
1864
1865        dmxsetfilter(dmxnode, pid, 0, 21);
1866        akttime = time(NULL);
1867
1868        while(self->aktion != STOP && self->aktion != PAUSE)
1869        {
1870                readlen = dvbread(dmxnode, channelbuf, 0, 3, 5000000);
1871                if(readlen <= 0)
1872                {
1873                        dmxclose(dmxnode, -1);
1874                        free(firstbuf);
1875                        return 1;
1876                }
1877                readlen = 0;
1878                len = channelbuf[2] | ((channelbuf[1] & 0x0f) << 8);
1879                if(len + 3 <= MINMALLOC)
1880                        readlen = dvbread(dmxnode, channelbuf, 3, len, 2000000);
1881                if(readlen <= 0)
1882                {
1883                        dmxclose(dmxnode, -1);
1884                        free(firstbuf);
1885                        return 1;
1886                }
1887
1888                //check for end
1889                if(first == 1)
1890                {
1891                        first = 0;
1892                        memcpy(firstbuf, channelbuf, readlen + 3);
1893                }
1894                else
1895                {
1896                        if(memcmp(firstbuf, channelbuf, readlen + 3) == 0)
1897                        {
1898                                debug(400, "opentv no more new data, wait for next run");
1899                                break;
1900                        }
1901
1902                        //stop epgscan after 2 min
1903                        if(akttime + 120 < time(NULL))
1904                        {
1905                                debug(400, "opentv timeout");
1906                                break;
1907                        }
1908                }
1909
1910                createopentvchannel(channelbuf, channel, flag);
1911        }
1912
1913        dmxclose(dmxnode, -1);
1914        free(firstbuf);
1915        return 0;
1916}
1917
1918//flag 0 = from epg thread
1919//flag 1 = from epg scan
1920int readopentvtitle(struct stimerthread* self, struct dvbdev* fenode, struct channel* chnode, unsigned char* channelbuf, int pid, int flag)
1921{
1922        int readlen = 0, first = 1, ret = 1, len = 0, count = 0;
1923        unsigned char *buf = NULL, *firstbuf = NULL;
1924        struct dvbdev* dmxnode;
1925        uint64_t transponderid = 0;
1926        int serviceid = 0;
1927        struct channel* tmpchnode = NULL;
1928        struct epg* epgnode = NULL;
1929        time_t dvbtime = 0, starttime = 0, endtime = 0, akttime = 0;
1930        time_t epgmaxsec = status.epgdays * 24 * 60 * 60;
1931        struct extepgcache* cache = NULL;
1932
1933        if(chnode == NULL) return 1;
1934
1935        buf = calloc(1, MINMALLOC);
1936        if(buf == NULL)
1937        {
1938                err("no memory");
1939                return 1;
1940        }
1941
1942        firstbuf = calloc(1, MINMALLOC);
1943        if(firstbuf == NULL)
1944        {
1945                err("no memory");
1946                free(buf);
1947                return 1;
1948        }
1949
1950        if(fenode == NULL) fenode = status.aktservice->fedev;
1951        if(fenode == NULL)
1952        {
1953                debug(400, "no frontend dev in service");
1954                free(buf);
1955                free(firstbuf);
1956                return 1;
1957        }
1958
1959        dmxnode = dmxopen(fenode, 0);
1960        if(dmxnode == NULL)
1961        {
1962                err("open demux dev");
1963                free(buf);
1964                free(firstbuf);
1965                return 1;
1966        }
1967
1968        dmxsetbuffersize(dmxnode, getconfigint("dmxepgbuffersize", NULL));
1969        dmxsetsource(dmxnode, fenode->fedmxsource);
1970
1971        dmxsetfilter(dmxnode, pid, 0, 22);
1972        akttime = time(NULL);
1973
1974        while(self->aktion != STOP && self->aktion != PAUSE)
1975        {
1976start:
1977                readlen = dvbread(dmxnode, buf, 0, 3, 2000000);
1978                if(readlen != 3)
1979                {
1980                        count++;
1981                        if(count < 5 && self->aktion != STOP && self->aktion != PAUSE) goto start;
1982                        break;
1983                }
1984
1985                readlen = 0;
1986                len = buf[2] | ((buf[1] & 0x0f) << 8);
1987                if(len + 3 <= MINMALLOC)
1988                        readlen = dvbread(dmxnode, buf, 3, len, 2000000);
1989                if(readlen <= 0)
1990                        break;
1991
1992                //check for end
1993                if(first == 1)
1994                {
1995                        first = 0;
1996                        memcpy(firstbuf, buf, readlen + 3);
1997                }
1998                else
1999                {
2000                        if(memcmp(firstbuf, buf, readlen + 3) == 0)
2001                        {
2002                                debug(400, "opentv no more new data, wait for next run");
2003                                break;
2004                        }
2005
2006                        //stop epgscan after 2 min
2007                        if(akttime + 120 < time(NULL))
2008                        {
2009                                debug(400, "opentv timeout");
2010                                break;
2011                        }
2012                }
2013
2014                int p = 0;
2015                unsigned short int channelid = 0;
2016                unsigned short int mjdtime = 0;
2017
2018                channelid = (buf[3] << 8) | buf[4];
2019                mjdtime = ((buf[8] << 8) | buf[9]);
2020                if(channelid > 0 && mjdtime > 0)
2021                {
2022                        p = 10;
2023                        while((p + 11) < readlen + 3)
2024                        {
2025                                unsigned short int eventid = 0;
2026                                unsigned char   desclen = 0;
2027                                unsigned short int packetlen = ((buf[p + 2] & 0x0f) << 8) | buf[p + 3];
2028
2029                                if((buf[p + 4] != 0xb5) || ((packetlen + p) > readlen + 3)) break;
2030
2031                                eventid = (buf[p] << 8) | buf[p + 1];
2032                                p += 4;
2033                                desclen = buf[p + 1] - 7;
2034
2035                                if((p + 9 + desclen) > readlen + 3) break;
2036
2037                                struct extepgchannel* extepgchannelnode = getextepgchannel(channelid);
2038                                if(extepgchannelnode != NULL)
2039                                {
2040                                        unsigned char tmpstr[256];
2041
2042                                        if(skyhuffmandecode(buf + p + 9, desclen, tmpstr, 256) != 0)
2043                                                tmpstr[0] = '\0';
2044                                        else
2045                                        {
2046                                                ret = 0;
2047
2048                                                //get start/endtime
2049                                                dvbtime = ((mjdtime - 40587) * 86400) + ((buf[p + 2] << 9) | (buf[p + 3] << 1));
2050                                                starttime = dvbtime;
2051                                                endtime = starttime + ((buf[p + 4] << 9) | (buf[p + 5] << 1));
2052
2053                                                tmpchnode = getchannel(extepgchannelnode->serviceid, extepgchannelnode->transponderid);
2054                                                if(tmpchnode == NULL)
2055                                                {
2056                                                        p += packetlen;
2057                                                        continue;
2058                                                }
2059
2060                                                //look in epglist if channel exists
2061                                                //only if epglist is marked as whitelist
2062                                                if(status.epglistmode == 2 || status.epglistmode == 3)
2063                                                {
2064                                                        if(getepgscanlist(serviceid, transponderid) == NULL)
2065                                                        {
2066                                                                p += packetlen;
2067                                                                continue;
2068                                                        }
2069                                                }
2070
2071                                                m_lock(&status.epgmutex, 4);
2072
2073                                                epgnode = getepg(tmpchnode, eventid, 1);
2074
2075#ifndef SIMULATE
2076                                                if(endtime < time(NULL) || starttime > time(NULL) + epgmaxsec)
2077                                                {
2078                                                        m_unlock(&status.epgmutex, 4);
2079                                                        p += packetlen;
2080                                                        continue;
2081                                                }
2082#endif
2083
2084                                                if(epgnode == NULL)
2085                                                        epgnode = addepg(tmpchnode, eventid, 0, starttime, endtime, NULL, 1);
2086                                                else
2087                                                        updateepg(tmpchnode, epgnode, eventid, 0, starttime, endtime, 1);
2088
2089                                                if(epgnode == NULL)
2090                                                {
2091                                                        m_unlock(&status.epgmutex, 4);
2092                                                        p += packetlen;
2093                                                        continue;
2094                                                }
2095
2096                                                epgnode->title = ostrcat((char*)tmpstr, NULL, 0, 0);
2097                                                cache = addextepgcache((channelid << 16) | eventid, epgnode, cache);
2098
2099                                                m_unlock(&status.epgmutex, 4);
2100                                        }
2101                                }
2102
2103                                p += packetlen;
2104                        }
2105                }
2106        }
2107
2108        dmxclose(dmxnode, -1);
2109        free(buf);
2110        free(firstbuf);
2111        return ret;
2112}
2113
2114int readopentvsummary(struct stimerthread* self, struct dvbdev* fenode, int pid)
2115{
2116        int readlen = 0, first = 1, ret = 1, len = 0, zret = 0, zlen = 0;
2117        unsigned char *buf = NULL, *firstbuf = NULL;
2118        struct dvbdev* dmxnode;
2119        time_t akttime = 0;
2120        struct extepgcache* cache = NULL;
2121        char* zbuf = NULL;
2122
2123        buf = calloc(1, MINMALLOC);
2124        if(buf == NULL)
2125        {
2126                err("no memory");
2127                return 1;
2128        }
2129
2130        firstbuf = calloc(1, MINMALLOC);
2131        if(firstbuf == NULL)
2132        {
2133                err("no memory");
2134                free(buf);
2135                return 1;
2136        }
2137
2138        if(fenode == NULL) fenode = status.aktservice->fedev;
2139        if(fenode == NULL)
2140        {
2141                debug(400, "no frontend dev in service");
2142                free(buf);
2143                free(firstbuf);
2144                return 1;
2145        }
2146
2147        dmxnode = dmxopen(fenode, 0);
2148        if(dmxnode == NULL)
2149        {
2150                err("open demux dev");
2151                free(buf);
2152                free(firstbuf);
2153                return 1;
2154        }
2155
2156        dmxsetbuffersize(dmxnode, getconfigint("dmxepgbuffersize", NULL));
2157        dmxsetsource(dmxnode, fenode->fedmxsource);
2158
2159        dmxsetfilter(dmxnode, pid, 0, 23);
2160        akttime = time(NULL);
2161
2162        while(self->aktion != STOP && self->aktion != PAUSE)
2163        {
2164                readlen = dvbread(dmxnode, buf, 0, 3, 2000000);
2165                if(readlen != 3)
2166                        break;
2167
2168                readlen = 0;
2169                len = buf[2] | ((buf[1] & 0x0f) << 8);
2170                if(len + 3 <= MINMALLOC)
2171                        readlen = dvbread(dmxnode, buf, 3, len, 2000000);
2172                if(readlen <= 0)
2173                        break;
2174
2175                //check for end
2176                if(first == 1)
2177                {
2178                        first = 0;
2179                        memcpy(firstbuf, buf, readlen + 3);
2180                }
2181                else
2182                {
2183                        if(memcmp(firstbuf, buf, readlen + 3) == 0)
2184                        {
2185                                debug(400, "opentv no more new data, wait for next run");
2186                                break;
2187                        }
2188
2189                        //stop epgscan after 2 min
2190                        if(akttime + 120 < time(NULL))
2191                        {
2192                                debug(400, "opentv timeout");
2193                                break;
2194                        }
2195                }
2196
2197                if(readlen + 3 < 20) continue;
2198
2199                int p = 0;
2200                unsigned short int channelid = (buf[3] << 8) | buf[4];
2201                unsigned short int mjdtime = (buf[8] << 8) | buf[9];
2202
2203                if((channelid > 0) && (mjdtime > 0))
2204                {
2205                        p = 10;
2206                        while(p < readlen + 3)
2207                        {
2208                                unsigned short int eventid = 0;
2209                                unsigned char desclen = 0;
2210                                unsigned short int packetlen = ((buf[p + 2] & 0x0f) << 8) | buf[p + 3];
2211
2212                                if((buf[p + 4] != 0xb9) || ((packetlen + p) > readlen + 3)) break;
2213
2214                                eventid = (buf[p] << 8) | buf[p + 1];
2215                                p += 4;
2216                                desclen = buf[p + 1];
2217
2218                                char tmpstr[MINMALLOC];
2219                                memset(tmpstr, 0, MINMALLOC);
2220
2221                                if(skyhuffmandecode(buf + p + 2, desclen, (unsigned char*)tmpstr, MINMALLOC) != 0)
2222                                        tmpstr[0] = '\0';
2223                                else
2224                                {
2225                                        cache = getextepgcache((channelid << 16) | eventid);
2226                                        if(cache != NULL && cache->epgnode != NULL)
2227                                        {
2228                                                ret = 0;
2229                                                //tmpstr = stringreplacechar(tmpstr, '\n', ' ');
2230
2231                                                //compress long desc
2232                                                if(tmpstr[0] != '\0')
2233                                                {
2234                                                        zret = ozip(tmpstr, strlen(tmpstr) + 1, &zbuf, &zlen, 1);
2235                                                        if(zret == 0)
2236                                                        {
2237                                                                free(cache->epgnode->desc); cache->epgnode->desc = NULL;
2238                                                                cache->epgnode->desc = zbuf;
2239                                                                cache->epgnode->desccomplen = zlen;
2240                                                        }
2241                                                }
2242                                        }
2243                                }
2244
2245                                p += packetlen;
2246                        }
2247                }
2248        }
2249
2250        dmxclose(dmxnode, -1);
2251        free(buf);
2252        free(firstbuf);
2253        return ret;
2254}
2255
2256//flag 0 = from epg thread
2257//flag 1 = from epg scan
2258int readopentv(struct stimerthread* self, struct channel* chnode, struct dvbdev* fenode, int flag)
2259{
2260        int ret = 0, i = 0;
2261        unsigned char* channelbuf = NULL;
2262        struct extepgconfig* extepgconfignode = NULL;
2263
2264        if(self == NULL) return 1;
2265
2266        if(chnode == NULL) chnode = status.aktservice->channel;
2267        if(chnode == NULL || (flag == 0 && chnode == status.aktservice->channel && status.aktservice->type != CHANNEL))
2268                return 1;
2269
2270        extepgconfignode = getextepgconfig(chnode->transponderid, 2);
2271        if(extepgconfignode == NULL)
2272        {
2273                debug(400, "transponder not found in extepgconfig");
2274                return 1;
2275        }
2276
2277        if(fenode == NULL) fenode = status.aktservice->fedev;
2278        if(fenode == NULL)
2279        {
2280                debug(400, "no frontend dev in service");
2281                return 1;
2282        }
2283
2284        channelbuf = calloc(1, MINMALLOC);
2285        if(channelbuf == NULL)
2286        {
2287                err("no memory");
2288                return 1;
2289        }
2290
2291        ret = loadopentv(extepgconfignode->file);
2292        if(ret != 0 || self->aktion == STOP || self->aktion == PAUSE)
2293        {
2294                debug(400, "opentv can't load dict");
2295                ret = 1;
2296                goto end;
2297        }
2298
2299        ret = readopentvchannel(self, fenode, chnode, channelbuf, extepgconfignode->channelpid, flag);
2300        if(ret != 0 || self->aktion == STOP || self->aktion == PAUSE)
2301        {
2302                debug(400, "opentv epg no channel found");
2303                ret = 1;
2304                goto end;
2305        }
2306
2307        ret = 1;
2308        for(i = 0; i < 8; i++)
2309        {
2310                if(extepgconfignode->titlepid[i] < 0) continue;
2311                if(self->aktion == STOP || self->aktion == PAUSE) break;
2312                int tmpret = readopentvtitle(self, fenode, chnode, channelbuf, extepgconfignode->titlepid[i], flag);
2313                if(tmpret == 0) ret = 0;
2314        }
2315        if(ret != 0 || self->aktion == STOP || self->aktion == PAUSE)
2316        {
2317                debug(400, "opentv epg no titles found");
2318                ret = 1;
2319                goto end;
2320        }
2321
2322        ret = 1;
2323        for(i = 0; i < 8; i++)
2324        {
2325                if(extepgconfignode->summarypid[i] < 0) continue;
2326                if(self->aktion == STOP || self->aktion == PAUSE) break;
2327                int tmpret = readopentvsummary(self, fenode, extepgconfignode->summarypid[i]);
2328                if(tmpret == 0) ret = 0;
2329        }
2330        if(ret != 0 || self->aktion == STOP || self->aktion == PAUSE)
2331        {
2332                debug(400, "opentv epg no summary found");
2333                ret = 1;
2334                goto end;
2335        }
2336
2337        ret = 0;
2338
2339end:
2340
2341        free(channelbuf); channelbuf = NULL;
2342        freeextepgchannel();
2343        freeextepgcache();
2344        freeopentv();
2345        return ret;
2346}
2347
2348#endif
Note: See TracBrowser for help on using the repository browser.