source: titan/titan/epg.h @ 15294

Last change on this file since 15294 was 15294, checked in by nit, 12 years ago

fix

File size: 38.2 KB
Line 
1#ifndef EPG_H
2#define EPG_H
3
4void debugepg()
5{
6        struct channel* chnode = channel;
7        struct epg* epgnode = NULL;
8
9        while(chnode != NULL)
10        {
11                if(chnode->epg != NULL)
12                {
13                        printf("\nChannel %s\n", chnode->name);
14                        epgnode = chnode->epg;
15                        while(epgnode != NULL)
16                        {
17                                printf("EventID: %d\n", epgnode->eventid);
18                                printf("Start: %ld\n", epgnode->starttime);
19                                printf("Stop: %ld\n", epgnode->endtime);
20                                printf("Title: %s\n", epgnode->title);
21                                printf("Subtitle: %s\n", epgnode->subtitle);
22                                //printf("Desc: %s\n", epgnode->desc);
23                                epgnode = epgnode->next;
24                        }
25                        printf("\n");
26                }
27                chnode = chnode->next;
28        }
29}
30
31void screensingleepg(struct channel* chnode, struct epg* epgnode, int flag)
32{
33        int rcret = 0, ret = 0, epgscreenconf = 0;
34        struct skin* singleepg = getscreen("singleepg");
35        struct skin* channelname = getscreennode(singleepg, "channelname");
36        struct skin* epgdesc = getscreennode(singleepg, "epgdesc");
37        struct skin* listbox = getscreennode(singleepg, "listbox");
38        struct skin* b2 = getscreennode(singleepg, "b2");
39        struct skin* b3 = getscreennode(singleepg, "b3");
40        struct skin* b4 = getscreennode(singleepg, "b4");
41        struct skin* tmp = NULL;
42        char* tmpstr = NULL, *buf = NULL;
43        struct tm *loctime = NULL;
44        struct epg* tmpepg = NULL;
45       
46        epgscreenconf = getconfigint("epg_screen", NULL);
47        listbox->aktline = 1;
48        listbox->aktpage = -1;
49
50        if(chnode == NULL) chnode = status.aktservice->channel;
51        if(chnode == NULL) return;
52        if(epgnode == NULL) epgnode = getepgakt(chnode);
53        tmpepg = epgnode;
54       
55        status.epgchannel = chnode;
56
57        changetext(channelname, chnode->name);
58        tmpstr = epgdescunzip(epgnode);
59        changetext(epgdesc, tmpstr);
60        free(tmpstr); tmpstr = NULL;
61       
62start:
63        buf = malloc(MINMALLOC);
64        if(buf == NULL)
65        {
66                err("no mem");
67                return;
68        }
69       
70        tmp = NULL;
71        delmarkedscreennodes(singleepg, 1);
72        delownerrc(singleepg);
73        epgnode = tmpepg;
74
75        while(epgnode != NULL)
76        {
77                tmp = addlistbox(singleepg, listbox, tmp, 1);
78                if(tmp != NULL)
79                {
80                        tmp->type = MULTIPROGRESSBAR;
81                        tmp->progresscol = listbox->progresscol;
82                        tmp->epgrecord = getepgrecord(chnode, epgnode);
83
84                        loctime = localtime(&epgnode->starttime);
85                        ostrftime(buf, MINMALLOC, listbox->param1, loctime);
86                        changetext(tmp, buf);
87                        changetext2(tmp, epgnode->title);
88                        tmp->handle = (char*)epgnode;
89                }
90                epgnode = epgnode->next;
91        }
92
93        free(buf); buf = NULL;
94
95        if(flag == 0 && epgscreenconf == 1)
96        {
97                b2->hidden = NO;
98                b3->hidden = NO;
99                b4->hidden = NO;
100        }
101        else
102        {
103                b2->hidden = YES;
104                b3->hidden = YES;
105                b4->hidden = YES;
106        }
107
108        drawscreen(singleepg, 0);
109        addscreenrc(singleepg, listbox);
110
111        while(1)
112        {
113                status.epgchannel = chnode;
114                status.screencalc = 2;
115                rcret = waitrc(singleepg, 0, 0);
116                status.screencalc = 0;
117                if((rcret == getrcconfigint("rcexit", NULL)) || (rcret == getrcconfigint("rcepg", NULL))) break;
118                if(rcret == getrcconfigint("rcinfo", NULL)) break;
119                if(rcret == getrcconfigint("rcok", NULL))
120                {
121                        servicecheckret(servicestart(chnode, NULL, NULL, 0), 0);
122                        break;
123                }
124                if(flag == 0 && epgscreenconf == 1 && rcret == getrcconfigint("rcgreen", NULL))
125                {
126                        if(listbox->select != NULL)
127                        {
128                                clearscreen(singleepg);
129                                screenepg(chnode, (struct epg*)listbox->select->handle, 0);
130                                //drawscreen(singleepg, 0);
131                                break;
132                        }
133                }
134                if(flag == 0 && epgscreenconf == 1 && rcret == getrcconfigint("rcyellow", NULL))
135                {
136                        clearscreen(singleepg);
137                        screenmultiepg(chnode, NULL, 0);
138                        //drawscreen(singleepg, 0);
139                        break;
140                }
141                if(flag == 0 && epgscreenconf == 1 && rcret == getrcconfigint("rcblue", NULL))
142                {
143                        clearscreen(singleepg);
144                        screengmultiepg(chnode, NULL, 0);
145                        //drawscreen(singleepg, 0);
146                        break;
147                }
148                if(listbox->select != NULL)
149                {
150                        tmpstr = epgdescunzip((struct epg*)listbox->select->handle);
151                        changetext(epgdesc, tmpstr);
152                        free(tmpstr); tmpstr = NULL;
153                        if(rcret == getrcconfigint("rcred", NULL))
154                        {
155                                clearscreen(singleepg);
156                                ret = addrecepg(chnode, (struct epg*)listbox->select->handle, NULL);
157                                goto start;
158                        }
159                        drawscreen(singleepg, 0);
160                }
161        }
162
163        status.epgchannel = NULL;
164        status.screencalc = 0;
165        delmarkedscreennodes(singleepg, 1);
166        delownerrc(singleepg);
167        clearscreen(singleepg);
168}
169
170void screenepg(struct channel* chnode, struct epg* epgnode, int flag)
171{
172        int rcret = 0, ret = 0, epgscreenconf = 0, min = 0;
173        struct skin* screenepg = getscreen("epg");
174        struct skin* channelname = getscreennode(screenepg, "channelname");
175        struct skin* channelnr = getscreennode(screenepg, "channelnr");
176        struct skin* epgtitle = getscreennode(screenepg, "epgtitle");
177        struct skin* epgsubtitle = getscreennode(screenepg, "epgsubtitle");
178        struct skin* epgstart = getscreennode(screenepg, "epgstart");
179        struct skin* epgend = getscreennode(screenepg, "epgend");
180        struct skin* epgtimeremaining = getscreennode(screenepg, "epgtimeremaining");
181        struct skin* epgdesc = getscreennode(screenepg, "epgdesc");
182        struct skin* rectimeline = getscreennode(screenepg, "rectimeline");
183        struct skin* b2 = getscreennode(screenepg, "b2");
184        struct skin* b3 = getscreennode(screenepg, "b3");
185        struct skin* b4 = getscreennode(screenepg, "b4");
186        struct skin* b5 = getscreennode(screenepg, "b5");
187        struct tm* loctime = NULL;
188        char* tmpstr = NULL, *buf = NULL;
189        void (*startplugin)(void);
190       
191        if(getconfigint("epgbutton", NULL) == 0)
192                changetext(b5, _("Single (EPG)"));
193        else
194                changetext(b5, _("Multi (EPG)"));
195
196        if(chnode == NULL) chnode = status.aktservice->channel;
197        if(chnode == NULL) return;
198        if(epgnode == NULL) epgnode = getepgakt(chnode);
199
200        status.epgchannel = chnode;
201        epgscreenconf = getconfigint("epg_screen", NULL);
202
203start:
204        epgdesc->aktpage = 1;
205        freeepgrecord(&rectimeline->epgrecord);
206        changetext(channelname, NULL);
207        changetext(epgtitle, NULL);
208        changetext(epgsubtitle, NULL);
209        changetext(epgdesc, NULL);
210        changetext(epgstart, NULL);
211        changetext(epgend, NULL);
212        changetext(epgtimeremaining, NULL);
213        changetext(channelnr, NULL);
214
215        if(flag == 0 && epgscreenconf == 0)
216        {
217                b2->hidden = NO;
218                b3->hidden = NO;
219                b4->hidden = NO;
220        }
221        else
222        {
223                b2->hidden = YES;
224                b3->hidden = YES;
225                b4->hidden = YES;
226        }
227
228        if(epgnode != NULL)
229        {
230                buf = malloc(MINMALLOC);
231                if(buf == NULL)
232                {
233                        err("no memory");
234                        return;
235                }
236
237                changetext(channelname, chnode->name);
238                changetext(epgtitle, epgnode->title);
239                changetext(epgsubtitle, epgnode->subtitle);
240                tmpstr = epgdescunzip(epgnode);
241                changetext(epgdesc, tmpstr);
242                free(tmpstr); tmpstr = NULL;
243
244                loctime = olocaltime(&epgnode->starttime);
245                if(loctime != NULL)
246                {
247                        ostrftime(buf, MINMALLOC, epgstart->param1, loctime);
248                        changetext(epgstart, buf);
249                        free(loctime); loctime = NULL;
250                }
251                loctime = olocaltime(&epgnode->endtime);
252                if(loctime != NULL)
253                {
254                        ostrftime(buf, MINMALLOC, epgend->param1, loctime);
255                        changetext(epgend, buf);
256                        free(loctime); loctime = NULL;
257                }
258               
259                if(epgnode->starttime <= time(NULL))
260                        min = (epgnode->endtime - (time(NULL) - 60)) / 60;
261                else
262                        min = (epgnode->endtime - epgnode->starttime) / 60;
263                if(min < 0) min = 0;
264                snprintf(buf, MINMALLOC, epgtimeremaining->param1, min);
265                changetext(epgtimeremaining, buf);
266
267                free(buf); buf = NULL;
268
269                tmpstr = getchannelnr(NULL, chnode);
270                changetext(channelnr, tmpstr);
271                free(tmpstr); tmpstr = NULL;
272               
273                rectimeline->epgrecord = getepgrecord(chnode, epgnode);
274        }
275
276        drawscreen(screenepg, 0);
277        addscreenrc(screenepg, epgdesc);
278
279        while(1)
280        {
281                status.epgchannel = chnode;
282                rcret = waitrc(screenepg, 0, 0);
283                if(rcret == getrcconfigint("rcexit", NULL)) break;
284                if(rcret == getrcconfigint("rcinfo", NULL)) break;
285                if(rcret == getrcconfigint("rcok", NULL))
286                {
287                        servicecheckret(servicestart(chnode, NULL, NULL, 0), 0);
288                        break;
289                }
290                if(rcret == getrcconfigint("rcright", NULL))
291                {
292                        if(epgnode != NULL && epgnode->next != NULL)
293                                epgnode = epgnode->next;
294                        goto start;
295                }
296                if(rcret == getrcconfigint("rcleft", NULL))
297                {
298                        if(epgnode != NULL && epgnode->prev != NULL && epgnode->endtime > time(NULL))
299                                epgnode = epgnode->prev;
300                        goto start;
301                }
302                if(flag == 0 && epgscreenconf == 0 && rcret == getrcconfigint("rcgreen", NULL))
303                {
304                        clearscreen(screenepg);
305                        screensingleepg(chnode, NULL, 0);
306                        //drawscreen(screenepg, 0);
307                        break;
308                }
309                if(flag == 0 && epgscreenconf == 0 && rcret == getrcconfigint("rcyellow", NULL))
310                {
311                        clearscreen(screenepg);
312                        screenmultiepg(chnode, NULL, 0);
313                        //drawscreen(screenepg, 0);
314                        break;
315                }
316                if(flag == 0 && epgscreenconf == 0 && rcret == getrcconfigint("rcblue", NULL))
317                {
318                        clearscreen(screenepg);
319                        screengmultiepg(chnode, NULL, 0);
320                        //drawscreen(screenepg, 0);
321                        break;
322                }
323                if(rcret == getrcconfigint("rcred", NULL))
324                {
325                        clearscreen(screenepg);
326                        ret = addrecepg(chnode, epgnode, NULL);
327                        //drawscreen(screenepg, 0);
328                        goto start;
329                }
330                if(rcret == getrcconfigint("rcepg", NULL))
331                {
332                        if(getconfigint("epgbutton", NULL) == 0)
333                        {
334                                clearscreen(screenepg);
335                                screensingleepg(chnode, NULL, 0);
336                                //drawscreen(screenepg, 0);
337                                break;
338                        }
339                        else
340                        {
341                                clearscreen(screenepg);
342                                screenmultiepg(chnode, NULL, 0);                               
343                                //drawscreen(screenepg, 0);
344                                break;
345                        }
346                }
347                if(rcret == getrcconfigint("rctext", NULL))
348                {
349                        struct skin* pluginnode = getplugin("Imdb");
350               
351                        if(pluginnode != NULL)
352                        {
353                                startplugin = dlsym(pluginnode->pluginhandle, "screenimdb");
354                                if(startplugin != NULL && epgnode != NULL)
355                                {
356                                        clearscreen(screenepg);
357                                        startplugin(epgnode->title);
358                                        drawscreen(screenepg, 0);
359                                }
360                        }
361                }
362        }       
363
364        status.epgchannel = NULL;
365        freeepgrecord(&rectimeline->epgrecord);
366        delownerrc(screenepg);
367        clearscreen(screenepg);
368}
369
370void epgchoice(struct channel* chnode)
371{
372        int epgscreenconf = 0;
373
374        epgscreenconf = getconfigint("epg_screen", NULL);
375        if(epgscreenconf == 1)
376                screensingleepg(chnode, NULL, 0);
377        else if(epgscreenconf == 2)
378                screenmultiepg(chnode, NULL, 0);
379        else if(epgscreenconf == 3)
380                screengmultiepg(chnode, NULL, 0);
381        else
382                screenepg(chnode, NULL, 0);
383}
384
385int writeepg(const char* filename)
386{
387        debug(1000, "in");
388        FILE *fd = NULL;
389        struct channel *chnode = channel;
390        struct epg* epgnode = NULL;
391        int ret, len = 0, count;
392       
393        m_lock(&status.epgmutex, 4);
394
395        fd = fopen(filename, "wbt");
396        if(fd == NULL)
397        {
398                perr("can't open %s", filename);
399                m_unlock(&status.epgmutex, 4);
400                return 1;
401        }
402
403        long long freespace = getfreespace((char*)filename);
404        long long epgfreespace = getconfigint("epgfreespace", NULL) * 1024;
405
406        while(chnode != NULL)
407        {
408                epgnode = chnode->epg;
409                while(epgnode != NULL)
410                {
411                        ret = 0, count = 0;
412                        ret += fwrite(&chnode->serviceid, sizeof(int), 1, fd); count++;
413                        freespace -= sizeof(int);
414                        ret += fwrite(&chnode->transponderid, sizeof(int), 1, fd); count++;
415                        freespace -= sizeof(int);
416                        ret += fwrite(&epgnode->eventid, sizeof(int), 1, fd); count++;
417                        freespace -= sizeof(int);
418                        ret += fwrite(&epgnode->version, sizeof(int), 1, fd); count++;
419                        freespace -= sizeof(int);
420                        ret += fwrite(&epgnode->parentalrating, sizeof(int), 1, fd); count++;
421                        freespace -= sizeof(int);
422                        ret += fwrite(&epgnode->starttime, sizeof(time_t), 1, fd); count++;
423                        freespace -= sizeof(time_t);
424                        ret += fwrite(&epgnode->endtime, sizeof(time_t), 1, fd); count++;
425                        freespace -= sizeof(time_t);
426
427                        len = 0;
428                        if(epgnode->title != NULL)
429                                len = strlen(epgnode->title);
430                        ret += fwrite(&len, sizeof(int), 1, fd); count++;
431                        freespace -= sizeof(int);
432                        if(epgnode->title != NULL && len > 0)
433                        {
434                                ret += fwrite(epgnode->title, len, 1, fd);
435                                freespace -= len;
436                                count++;
437                        }
438
439                        len = 0;
440                        if(epgnode->subtitle != NULL)
441                                len = strlen(epgnode->subtitle);
442                        ret += fwrite(&len, sizeof(int), 1, fd); count++;
443                        freespace -= sizeof(int);
444                        if(epgnode->subtitle != NULL && len > 0)
445                        {
446                                ret += fwrite(epgnode->subtitle, len, 1, fd);
447                                freespace -= len;
448                                count++;
449                        }
450
451                        if(epgnode->desc == NULL)
452                        {
453                                epgnode->desclen = 0;
454                                epgnode->desccomplen = 0;
455                        }
456                        ret += fwrite(&epgnode->desclen, sizeof(int), 1, fd); count++;
457                        freespace -= sizeof(int);
458                        ret += fwrite(&epgnode->desccomplen, sizeof(int), 1, fd); count++;
459                        freespace -= sizeof(int);
460
461                        len = epgnode->desccomplen;
462                        if(len == 0)
463                                len = epgnode->desclen;
464                        if(epgnode->desc != NULL)
465                        {
466                                ret += fwrite(epgnode->desc, len, 1, fd);
467                                freespace -= len;
468                                count++;
469                        }
470
471                        if(ret != count)
472                        {
473                                perr("writting file %s", filename);
474                        }
475
476                        if(freespace < epgfreespace)
477                                break;
478                        epgnode = epgnode->next;
479                }
480                if(freespace < epgfreespace)
481                {
482                        err("not all data written freespace=%lld epgfreespace=%lld (%s)", freespace, epgfreespace, filename);
483                        break;
484                }
485                chnode = chnode->next;
486        }
487
488        fclose(fd);
489        debug(1000, "out");
490        m_unlock(&status.epgmutex, 4);
491        return 0;
492}
493
494char* epgdescunzip(struct epg* epgnode)
495{
496        int ret = 0, zlen = 0;
497        char* zbuf = NULL;
498
499        if(epgnode == NULL)
500        {
501                debug(1000, "out -> NULL detect");
502                return NULL;
503        }
504
505        if(epgnode->desccomplen < 1)
506                return ostrcat(epgnode->desc, "", 0, 0);
507
508        ret = ounzip(epgnode->desc, epgnode->desccomplen, &zbuf, &zlen, MINMALLOC, 0);
509        if(ret == 0)
510                return zbuf;
511
512        return NULL;
513}
514
515struct epg* getepgbytime(struct channel* chnode, time_t akttime)
516{
517        debug(1000, "in");
518
519        m_lock(&status.epgmutex, 4);
520
521        if(chnode == NULL || chnode->epg == NULL)
522        {
523                debug(1000, "out-> NULL detect");
524                m_unlock(&status.epgmutex, 4);
525                return NULL;
526        }
527
528        struct epg *node = chnode->epg;
529
530        while(node != NULL)
531        {
532                if(node->starttime <= akttime && node->endtime > akttime)
533                {
534                        debug(1000, "out");
535                        m_unlock(&status.epgmutex, 4);
536                        return node;
537                }
538
539                node = node->next;
540        }
541
542        m_unlock(&status.epgmutex, 4);
543        return NULL;
544}
545
546struct epg* getepgakt(struct channel* chnode)
547{
548#ifdef SIMULATE
549        time_t akttime = 1307871000;
550        //akttime = 1315614900;
551        //akttime = 1317927300;
552        //akttime = 1307971000;
553#else
554        time_t akttime = time(NULL);
555#endif
556        return getepgbytime(chnode, akttime);
557}
558
559//flag 0: lock
560//flag 1: nolock
561struct epg* getepg(struct channel* chnode, int eventid, int flag)
562{
563        if(chnode == NULL)
564        {
565                debug(1000, "out-> NULL detect");
566                return NULL;
567        }
568
569        if(flag == 0) m_lock(&status.epgmutex, 4);
570
571        struct epg *node = chnode->epg;
572
573        while(node != NULL)
574        {
575                if(node->eventid == eventid)
576                {
577                        if(flag == 0) m_unlock(&status.epgmutex, 4);
578                        return node;
579                }
580
581                node = node->next;
582        }
583        if(flag == 0) m_unlock(&status.epgmutex, 4);
584        return NULL;
585}
586
587//flag 0: lock
588//flag 1: nolock
589struct epg* updateepg(struct channel* chnode, struct epg* epgnode, int eventid, int version, time_t starttime, time_t endtime, int flag)
590{
591//      debug(1000, "in");
592        int changetime = 0;
593
594        if(chnode == NULL || epgnode == NULL)
595        {
596                debug(1000, "out-> NULL detect");
597                return NULL;
598        }
599
600        if(flag == 0) m_lock(&status.epgmutex, 4);
601
602        struct epg *prev = NULL, *node = chnode->epg;
603
604        epgnode->eventid = eventid;
605        epgnode->version = version;
606        if(epgnode->starttime != starttime)
607        {
608                changetime = 1;
609                epgnode->starttime = starttime;
610        }
611        epgnode->endtime = endtime;
612
613        if(changetime == 1)
614        {
615                if(chnode->epg == epgnode)
616                {
617                        chnode->epg = epgnode->next;
618                        node = chnode->epg;
619                }
620
621                if(epgnode->prev != NULL) epgnode->prev->next = epgnode->next;
622                if(epgnode->next != NULL) epgnode->next->prev = epgnode->prev;
623                epgnode->prev = NULL;
624                epgnode->next = NULL;
625
626                while(node != NULL && epgnode->starttime >= node->starttime)
627                {
628                        prev = node;
629                        node = node->next;
630                }
631
632                if(prev == NULL)
633                        chnode->epg = epgnode;
634                else
635                {
636                        prev->next = epgnode;
637                        epgnode->prev = prev;
638                }
639                epgnode->next = node;
640                if(node != NULL) node->prev = epgnode;
641        }
642
643        if(flag == 0) m_unlock(&status.epgmutex, 4);
644//      debug(1000, "out");
645        return epgnode;
646}
647
648//flag 0: lock
649//flag 1: nolock
650struct epg* addepg(struct channel* chnode, int eventid, int version, time_t starttime, time_t endtime, struct epg* last, int flag)
651{
652//      debug(1000, "in");
653
654        if(chnode == NULL)
655        {
656                debug(1000, "out-> NULL detect");
657                return NULL;
658        }
659
660        if(flag == 0) m_lock(&status.epgmutex, 4);
661
662        struct epg *newnode = NULL, *prev = NULL, *node = chnode->epg;
663
664        newnode = (struct epg*)malloc(sizeof(struct epg));     
665        if(newnode == NULL)
666        {
667                err("no memory");
668                if(flag == 0) m_unlock(&status.epgmutex, 4);
669                return NULL;
670        }
671
672        memset(newnode, 0, sizeof(struct epg));
673
674        newnode->eventid = eventid;
675        newnode->version = version;
676        newnode->starttime = starttime;
677        newnode->endtime = endtime;
678
679        if(last == NULL)
680        {
681                while(node != NULL && newnode->starttime >= node->starttime)
682                {
683                        prev = node;
684                        node = node->next;
685                }
686        }
687        else
688        {
689                prev = last;
690                node = last->next;
691        }
692
693        if(prev == NULL)
694                chnode->epg = newnode;
695        else
696        {
697                prev->next = newnode;
698                newnode->prev = prev;
699        }
700        newnode->next = node;
701        if(node != NULL) node->prev = newnode;
702
703        if(flag == 0) m_unlock(&status.epgmutex, 4);
704//      debug(1000, "out");
705        return newnode;
706}
707
708//flag 0: lock
709//flag 1: nolock
710void delepg(struct channel* chnode, struct epg* epgnode, int flag)
711{
712        debug(1000, "in");
713
714        if(chnode == NULL)
715        {
716                debug(1000, "out-> NULL detect");
717                return;
718        }
719
720        if(flag == 0) m_lock(&status.epgmutex, 4);
721
722        struct epg *node = chnode->epg, *prev = chnode->epg;
723
724        while(node != NULL)
725        {
726                if(node == epgnode)
727                {
728                        if(node == chnode->epg)
729                        {
730                                chnode->epg = node->next;
731                                if(chnode->epg != NULL)
732                                        chnode->epg->prev = NULL;
733                        }
734                        else
735                        {
736                                prev->next = node->next;
737                                if(prev->next != NULL)
738                                        prev->next->prev = prev;
739                        }
740
741                        free(node->title);
742                        node->title = NULL;
743                        free(node->subtitle);
744                        node->subtitle = NULL;
745                        free(node->desc);
746                        node->desc = NULL;
747
748                        free(node);
749                        node = NULL;
750                        break;
751                }
752
753                prev = node;
754                node = node->next;
755        }
756        if(flag == 0) m_unlock(&status.epgmutex, 4);
757        debug(1000, "out");
758}
759
760void freeepg(struct channel* chnode)
761{
762        debug(1000, "in");
763
764        if(chnode == NULL)
765        {
766                debug(1000, "out-> NULL detect");
767                return;
768        }
769
770        m_lock(&status.epgmutex, 4);
771        struct epg *node = chnode->epg, *prev = chnode->epg;
772
773        while(node != NULL)
774        {
775                prev = node;
776                node = node->next;
777                if(prev != NULL)
778                        delepg(chnode, prev, 1);
779        }
780        m_unlock(&status.epgmutex, 4);
781        debug(1000, "out");
782}
783
784void resetepg()
785{
786        struct channel *node = channel;
787        char* tmpstr = NULL;
788
789        //stop epgscanlistthread
790        if(status.epgscanlistthread != NULL)
791                status.epgscanlistthread->aktion = STOP;
792
793        if(status.epgthread != NULL)
794                status.epgthread->aktion = PAUSE;
795
796        //wait a little for thread end/pause
797        sleep(1);
798
799        while(node != NULL)
800        {
801                freeepg(node);
802                node = node->next;
803        }
804
805        tmpstr = createpath(getconfig("epg_path", NULL), "epg.dat");
806        unlink(tmpstr);
807        free(tmpstr); tmpstr = NULL;
808
809        if(status.epgthread != NULL)
810                status.epgthread->aktion = START;
811}
812
813void deloldepg()
814{
815        struct channel* chnode = channel;
816        struct epg* epgnode = NULL;
817
818        m_lock(&status.epgmutex, 4);
819        while(chnode != NULL)
820        {
821                if(chnode->epg != NULL)
822                {
823                        epgnode = channel->epg;
824                        while(epgnode != NULL)
825                        {
826                                if(epgnode->endtime + 60 < time(NULL))
827                                        delepg(chnode, epgnode, 1);
828                                epgnode = epgnode->next;
829                        }
830                }
831                chnode = chnode->next;
832        }
833        m_unlock(&status.epgmutex, 4);
834}
835
836/*
837//Parse language-id translation file
838char *eitlang(u_char *l)
839{
840        static union lookup_key lang;
841        lang.c[0] = (char)l[0];
842        lang.c[1] = (char)l[1];
843        lang.c[2] = (char)l[2];
844        lang.c[3] = '\0';
845
846        char *c = lookup(languageid_table, lang.i);
847        return c ? c : lang.c;
848}
849*/
850
851//Parse 0x4D Short Event Descriptor
852void eventdesc(struct channel* chnode, struct epg* epgnode, void *buf)
853{
854        struct transponder* tpnode = NULL;
855        struct eitshortevent *evtdesc = buf;
856        char* title = NULL, *subtitle = NULL;
857        int evtlen = evtdesc->event_name_length;
858        int dsclen = 0;
859
860        if(!evtlen) return;
861        if(chnode != NULL) tpnode = chnode->transponder;
862
863        //title
864        title = malloc(evtlen + 1);
865        if(title == NULL)
866        {
867                err("no mem");
868                return;
869        }
870        memcpy(title, (char *)&evtdesc->data, evtlen);
871        title[evtlen] = '\0';
872        free(epgnode->title);
873        epgnode->title = strutf8(tpnode, title, evtlen, 0, 1, 0);
874
875        //subtitle
876        dsclen = evtdesc->data[evtlen];
877        subtitle = malloc(dsclen + 1);
878        if(subtitle == NULL)
879        {
880                err("no mem");
881                return;
882        }
883        memcpy(subtitle, (char *)&evtdesc->data[evtlen + 1], dsclen);
884        subtitle[dsclen] = '\0';
885        free(epgnode->subtitle);
886        epgnode->subtitle = strutf8(tpnode, subtitle, dsclen, 0, 1, 0);
887}
888
889void epgadddesc(struct epg* epgnode, char* desc)
890{
891        int len = 0;
892       
893        if(desc != NULL) len = strlen(desc);
894        epgnode->desclen += len;
895
896        epgnode->desc = realloc(epgnode->desc, epgnode->desclen + 1);
897        if(epgnode->desc == NULL)
898        {
899                err("no mem");
900                epgnode->desclen = 0;
901                return;
902        }
903        memcpy(epgnode->desc + epgnode->desclen - len, desc, len + 1);
904}
905
906// Parse 0x4E Extended Event Descriptor
907void longeventdesc(struct channel* chnode, struct epg* epgnode, unsigned char *buf)
908{
909        struct transponder* tpnode = NULL;
910        struct eitlongevent *levt = (struct eitlongevent*)buf;
911        char* desc = NULL;
912
913        if(chnode != NULL) tpnode = chnode->transponder;
914        int nonempty = (levt->descriptor_number || levt->last_descriptor_number || levt->length_of_items || levt->data[0]);
915
916        void *p = &levt->data;
917        while(p < (void *)levt->data + levt->length_of_items)
918        {
919                struct eitlongeventitem *name = p;
920                int namelen = name->item_description_length;
921                desc = malloc(namelen + 1);
922                if(desc == NULL)
923                {
924                        err("no mem");
925                        return;
926                }
927                memcpy(desc, (char *)&name->data, namelen);
928                desc[namelen] = '\0';
929                desc = strutf8(tpnode, desc, namelen, 0, 1, 0);
930                epgadddesc(epgnode, desc);
931                free(desc); desc = NULL;
932                p += EITLONGEVENTITEMLEN + namelen;
933
934                struct eitlongeventitem *value = p;
935                int valuelen = value->item_description_length;
936                desc = malloc(valuelen + 1);
937                if(desc == NULL)
938                {
939                        err("no mem");
940                        return;
941                }
942                memcpy(desc, (char *)&value->data, valuelen);
943                desc[valuelen] = '\0';
944                desc = strutf8(tpnode, desc, valuelen, 0, 1, 0);
945                epgadddesc(epgnode, desc);
946                free(desc); desc = NULL;
947                p += EITLONGEVENTITEMLEN + valuelen;
948        }
949
950        struct eitlongeventitem *text = p;
951        int textlen = text->item_description_length;
952        if(nonempty && textlen)
953        {
954                desc = malloc(textlen + 1);
955                if(desc == NULL)
956                {
957                        err("no mem");
958                        return;
959                }
960                memcpy(desc, (char *)&text->data, textlen);
961                desc[textlen] = '\0';
962                desc = strutf8(tpnode, desc, textlen, 0, 1, 0);
963                epgadddesc(epgnode, desc);
964                free(desc); desc = NULL;
965        }
966
967        free(desc); desc = NULL;
968}
969
970// Parse 0x55 Rating Descriptor
971void ratingdescr(struct epg* epgnode, unsigned char *buf)
972{
973        struct parentalrating *pr = (struct parentalrating*)buf;
974        void *p = NULL;
975
976        for(p = &pr->data; p < (void*)buf + pr->descriptor_length; p += PARENTALRATINGITEMLEN)
977        {
978                struct parentalratingitem *pr = p;
979                switch(pr->rating)
980                {
981                        case 0x00: //undefined
982                                break;
983                        case 0x01 ... 0x0F:
984                                epgnode->parentalrating = pr->rating + 3;
985                                break;
986                        case 0x10 ... 0xFF: //broadcaster defined
987                                break;
988                }
989        }
990}
991
992// Parse 0x4A Linkage Descriptor
993void linkagedesc(struct channel* chnode, struct epg* epgnode, void *buf)
994{
995        struct eitlinkage *evtlink = buf;
996        unsigned long transponderid = 0;
997       
998        int tid = HILO(evtlink->transport_stream_id);
999        int onid = HILO(evtlink->original_network_id);
1000        int serviceid = HILO(evtlink->service_id);
1001       
1002        transponderid = (onid << 16) | tid;
1003
1004        if(getlinkedchannel(chnode, serviceid, transponderid) == NULL)
1005                addlinkedchannel(chnode, serviceid, transponderid, NULL);
1006}
1007
1008#if 0
1009// Parse 0x50 Component Descriptor
1010void componentdescr(struct epg* epgnode, unsigned char *buf)
1011{
1012        struct eitcomponent *dc = buf;
1013
1014        switch(dc->stream_content)
1015        {
1016                case 0x01: // Video Info
1017                        //if ((dc->component_type - 1) & 0x08) //HD TV
1018                        //if ((dc->component_type - 1) & 0x04) //30Hz else 25
1019                        printf("aspect %s\n", lookup(aspect_table, (dc->component_type - 1) & 0x03));
1020                        break;
1021                case 0x02: // Audio Info
1022                        printf("stereo %s\n", lookup(audio_table, (dc->component_type)));
1023                        printf("language %d\n", dc->lang_code1);
1024                        break;
1025                case 0x03: // Teletext Info
1026                        // if ((dc->component_type) & 0x10) //subtitles
1027                        // if ((dc->component_type) & 0x20) //subtitles for hard of hearing
1028                        printf("txt language %d\n", dc->lang_code1);
1029                        break;
1030                // case 0x04: // AC3 info
1031        }
1032#if 0
1033        printf("StreamContent %d\n", dc->stream_content);
1034        printf("ComponentType %x\n", dc->component_type);
1035        printf("ComponentTag %x\n", dc->component_tag);
1036        printf("Length %d\n", dc->descriptor_length - 6);
1037#endif
1038}
1039
1040inline void eitsetbit(int *bf, int b)
1041{
1042        int i = b / 8 / sizeof(int);
1043        int s = b % (8 * sizeof(int));
1044        bf[i] |= (1 << s);
1045}
1046
1047inline bool eitgetbit(int *bf, int b)
1048{
1049        int i = b / 8 / sizeof(int);
1050        int s = b % (8 * sizeof(int));
1051        return bf[i] & (1 << s);
1052}
1053
1054// Parse 0x54 Content Descriptor
1055void contentdescr(struct epg* epgnode, unsigned char *buf)
1056{
1057        struct eitcontent *dc = buf;
1058
1059        int once[256/8/sizeof(int)] = {0,};
1060        void *p;
1061        for(p = &dc->data; p < data + dc->descriptor_length; p += NIBBLE_CONTENT_LEN)
1062        {
1063                struct nibble_content *nc = p;
1064                int c1 = (nc->content_nibble_level_1 << 4) + nc->content_nibble_level_2;
1065#ifdef CATEGORY_UNKNOWN
1066                int c2 = (nc->user_nibble_1 << 4) + nc->user_nibble_2;
1067#endif
1068                if(c1 > 0 && !eitgetbit(once, c1))
1069                {
1070                        eitsetbit(once, c1);
1071                        char *c = lookup(description_table, c1);
1072                        if(c)
1073                                if(c[0])
1074                                        printf("\t<category>%s</category>\n", c);
1075#ifdef CATEGORY_UNKNOWN
1076                                else
1077                                        printf("\t<!--category>%s %02X %02X</category-->\n", c+1, c1, c2);
1078                        else
1079                                printf("\t<!--category>%02X %02X</category-->\n", c1, c2);
1080#endif
1081                }
1082                // This is weird in the uk, they use user but not content, and almost the same values
1083        }
1084}
1085
1086// Parse 0x5F Private Data Specifier
1087int privatedataspecifier(struct epg* epgnode, unsigned char *buf)
1088{
1089        return GetPrivateDataSpecifier(data);
1090}
1091
1092// Parse 0x76 Content Identifier Descriptor
1093void contentidentifierdesc(struct epg* epgnode, unsigned char *buf)
1094{
1095        struct descr_content_identifier *ci = data;
1096        void *p;
1097        for(p = &ci->data; p < data + ci->descriptor_length; /* at end */)
1098        {
1099                struct descr_content_identifier_crid *crid = p;
1100                struct descr_content_identifier_crid_local *crid_data;
1101
1102                int crid_length = 3;
1103
1104                char type_buf[32];
1105                char *type;
1106                char buf[256];
1107
1108                type = lookup(crid_type_table, crid->crid_type);
1109                if(type == NULL)
1110                {
1111                        type = type_buf;
1112                        sprintf(type_buf, "0x%2x", crid->crid_type);
1113                }
1114
1115                switch(crid->crid_location)
1116                {
1117                        case 0x00: /* Carried explicitly within descriptor */
1118                                crid_data = (descr_content_identifier_crid_local_t *)&crid->crid_ref_data;
1119                                int cridlen = crid_data->crid_length;
1120                                assert(cridlen < sizeof(buf));
1121                                memcpy(buf, (char *)&crid_data->crid_byte, cridlen);
1122                                buf[cridlen] = '\0';
1123
1124                                printf("\t<crid type='%s'>%s</crid>\n", type, xmlify(buf));
1125                                crid_length = 2 + crid_data->crid_length;
1126                                break;
1127                        case 0x01: /* Carried in Content Identifier Table (CIT) */
1128                                break;
1129                        default:
1130                                break;
1131                }
1132                p += crid_length;
1133        }
1134}
1135#endif
1136
1137//Parse Descriptor
1138void parseeitdesc(struct channel* chnode, struct epg* epgnode, unsigned char *buf, int len, int nolongdesc)
1139{
1140        unsigned char *p;
1141        for(p = buf; p < buf + len; p += 2 + p[1])
1142        {
1143                switch((int)p[0])
1144                {
1145                        case 0:
1146                                break;
1147                        case 0x4A:
1148                                linkagedesc(chnode, epgnode, p);
1149                                break;
1150                        case 0x4D:
1151                                eventdesc(chnode, epgnode, p);
1152                                break;
1153                        case 0x4E:
1154                                if(nolongdesc == 0)
1155                                        longeventdesc(chnode, epgnode, p);
1156                                break;
1157                        case 0x55:
1158                                ratingdescr(epgnode, p);
1159                                break;
1160/*
1161                        case 0x50:
1162                                componentdescr(epgnode, p, LANGUAGE);
1163                                componentdescr(epgnode, p, VIDEO);
1164                                componentdescr(epgnode, p, AUDIO);
1165                                componentdescr(epgnode, p, SUBTITLES);
1166                                break;
1167                        case 0x53: // CA Identifier Descriptor
1168                                break;
1169                        case 0x54:
1170                                contentdescr(epgnode, p);
1171                                break;
1172                        case 0x5f: // Private Data Specifier
1173                                pds = privatedataspecifier(epgnode, p);
1174                                break;
1175                        case 0x64: // Data broadcast desc - Text Desc for Data components
1176                                break;
1177                        case 0x69: // Programm Identification Label
1178                                break;
1179                        case 0x81: // TODO ???
1180                                if(pds == 5) // ARD_ZDF_ORF
1181                                        break;
1182                        case 0x82: // VPS (ARD, ZDF, ORF)
1183                                if(pds == 5) // ARD_ZDF_ORF
1184                                        // TODO: <programme @vps-start="???">
1185                                        break;
1186                        case 0x4F: // Time Shifted Event
1187                        case 0x52: // Stream Identifier Descriptor
1188                        case 0x5E: // Multi Lingual Component Descriptor
1189                        case 0x83: // Logical Channel Descriptor (some kind of news-ticker on ARD-MHP-Data?)
1190                        case 0x84: // Preferred Name List Descriptor
1191                        case 0x85: // Preferred Name Identifier Descriptor
1192                        case 0x86: // Eacem Stream Identifier Descriptor
1193                                break;
1194                        case 0x76:
1195                                contentidentifierdesc(epgnode, p);
1196                                break;
1197*/
1198                }
1199        }
1200}
1201
1202// Parse Event Information Table
1203//flag 0 = end only on channelswitch / or stop sig
1204//flag 1 = end after each run
1205void parseeit(struct channel* chnode, unsigned char *buf, int len, int flag)
1206{
1207        struct eit* eit = (struct eit*)buf;
1208        unsigned char *p;
1209        time_t dvbtime = 0, starttime = 0, endtime = 0;
1210        struct channel* tmpchnode = NULL;
1211        struct epg* epgnode = NULL;
1212        char* zbuf = NULL;
1213        int zlen = 0, ret = 0, eitlen = 0;
1214        time_t epgmaxsec = status.epgdays * 24 * 60 * 60;
1215        unsigned long transponderid = 0;
1216        int serviceid = 0, eventid = 0;
1217        int nolongdesc = 0;
1218
1219        len -= 4; //remove CRC
1220        if(chnode == NULL) chnode = status.aktservice->channel;
1221
1222        // For each event listing
1223        for (p = (unsigned char*)&eit->data; p < buf + len; p += EITEVENTLEN + GETEITDESCLEN(p))
1224        {
1225                nolongdesc = 0;
1226                struct eitevent* evt = (struct eitevent*)p;
1227
1228                // No program info at end! Just skip it
1229                eitlen = GETEITDESCLEN(evt);
1230                if(eitlen == 0 || chnode == NULL)
1231                        return;
1232                if(chnode == status.aktservice->channel && status.aktservice->type != CHANNEL)
1233                        return;
1234               
1235                transponderid = (HILO(eit->original_network_id) << 16) | HILO(eit->transport_stream_id);
1236                serviceid = HILO(eit->service_id);
1237                tmpchnode = getchannel(serviceid, transponderid);
1238                if(tmpchnode == NULL)
1239                {
1240                        debug(1000, "out -> NULL detect");
1241                        continue;
1242                }
1243
1244                //look in epglist if channel exists
1245                //only if epglist is marked as whitelist
1246                if(status.epglistmode == 2 || status.epglistmode == 3)
1247                {
1248                        if(getepgscanlist(serviceid, transponderid) == NULL)
1249                                continue;
1250                }
1251
1252                m_lock(&status.epgmutex, 4);
1253                eventid = HILO(evt->event_id);
1254                epgnode = getepg(tmpchnode, eventid, 1);
1255
1256                dvbtime = dvbconvertdate(&evt->mjd_hi, 0);
1257                starttime = dvbtime;
1258                starttime -= starttime % 60;
1259
1260                dvbtime += bcdtoint(evt->duration_s & 0xff);
1261                dvbtime += (bcdtoint(evt->duration_m & 0xff) * 60);
1262                dvbtime += (bcdtoint(evt->duration_h & 0xff) * 60 * 60);
1263                endtime = dvbtime;
1264                endtime -= endtime % 60;
1265
1266#ifndef SIMULATE
1267                if(endtime < time(NULL) || starttime > time(NULL) + epgmaxsec)
1268                {
1269                        m_unlock(&status.epgmutex, 4);
1270                        continue;
1271                }
1272#endif
1273
1274                if(epgnode == NULL)
1275                                epgnode = addepg(tmpchnode, eventid, eit->version_number, starttime, endtime, NULL, 1);
1276                else
1277                {
1278                        updateepg(tmpchnode, epgnode, eventid, eit->version_number, starttime, endtime, 1);
1279                        if(epgnode->desc != NULL)
1280                                nolongdesc = 1;
1281                }
1282
1283                if(epgnode == NULL)
1284                {
1285                        debug(1000, "out -> NULL detect");
1286                        m_unlock(&status.epgmutex, 4);
1287                        continue;
1288                }
1289
1290                //1 Airing, 2 Starts in a few seconds, 3 Pausing, 4 About to air
1291                //printf("RunningStatus %d\n", evt->running_status);
1292
1293                parseeitdesc(tmpchnode, epgnode, (unsigned char*)&evt->data, eitlen, nolongdesc);
1294                //compress long desc
1295                if(nolongdesc == 0 && epgnode->desc != NULL)
1296                {
1297                        ret = zip(epgnode->desc, strlen(epgnode->desc) + 1, &zbuf, &zlen, 1);
1298                        if(ret == 0)
1299                        {
1300                                free(epgnode->desc); epgnode->desc = NULL;
1301                                epgnode->desc = zbuf;
1302                                epgnode->desccomplen = zlen;
1303                        }
1304                }
1305                m_unlock(&status.epgmutex, 4);
1306        }
1307}
1308
1309int readepg(const char* filename)
1310{
1311        debug(1000, "in");
1312        FILE *fd = NULL;
1313        struct channel *chnode = channel, *oldchnode = NULL;
1314        struct epg* epgnode = NULL;
1315        int ret = 0, len = 0;
1316        time_t epgmaxsec = status.epgdays * 24 * 60 * 60;
1317
1318        fd = fopen(filename, "rb");
1319        if(fd == NULL)
1320        {
1321                perr("can't open %s", filename);
1322                return 1;
1323        }
1324       
1325        m_lock(&status.epgmutex, 4);
1326
1327        while(!feof(fd))
1328        {
1329                int serviceid = 0, transponderid = 0, eventid = 0;
1330                int version = 0, starttime = 0, endtime = 0;
1331                int desclen = 0, desccomplen = 0, parentalrating = 0;
1332                char* title = NULL, *subtitle = NULL, *desc = NULL;
1333
1334                ret = fread(&serviceid, sizeof(int), 1, fd);
1335                if(feof(fd)) break;
1336                ret = fread(&transponderid, sizeof(int), 1, fd);
1337                ret = fread(&eventid, sizeof(int), 1, fd);
1338                ret = fread(&version, sizeof(int), 1, fd);
1339                ret = fread(&parentalrating, sizeof(int), 1, fd);
1340                ret = fread(&starttime, sizeof(time_t), 1, fd);
1341                ret = fread(&endtime, sizeof(time_t), 1, fd);
1342
1343                len = 0;
1344                ret = fread(&len, sizeof(int), 1, fd);
1345                if(len > 0)
1346                {
1347                        title = malloc(len + 1);
1348                        if(title == NULL)
1349                        {
1350                                err("title no mem %d", len);
1351                                fclose(fd);
1352                                m_unlock(&status.epgmutex, 4);
1353                                return 1;
1354                        }
1355                        ret = fread(title, len, 1, fd);
1356                        title[len] = '\0';
1357                }
1358       
1359                len = 0;
1360                ret = fread(&len, sizeof(int), 1, fd);
1361                if(len > 0)
1362                {
1363                        subtitle = malloc(len + 1);
1364                        if(subtitle == NULL)   
1365                        {
1366                                err("subtitle no mem %d", len);
1367                                free(title); title = NULL;
1368                                fclose(fd);
1369                                m_unlock(&status.epgmutex, 4);
1370                                return 1;
1371                        }
1372                        ret = fread(subtitle, len, 1, fd);
1373                        subtitle[len] = '\0';
1374                }
1375
1376                ret = fread(&desclen, sizeof(int), 1, fd);
1377                ret = fread(&desccomplen, sizeof(int), 1, fd);
1378       
1379                len = desccomplen;
1380                if(len == 0)
1381                        len = desclen;
1382                if(len > 0)
1383                {
1384                        if(desccomplen == 0)
1385                                desc = malloc(len + 1);
1386                        else
1387                                desc = malloc(len);
1388                        if(desc == NULL)
1389                        {
1390                                err("desc no mem %d", len);
1391                                free(title); title = NULL;
1392                                free(subtitle); subtitle = NULL;
1393                                fclose(fd);
1394                                m_unlock(&status.epgmutex, 4);
1395                                return 1;
1396                        }
1397                        ret = fread(desc, len, 1, fd);
1398                        if(desccomplen == 0)
1399                                desc[len] = '\0';
1400                }
1401
1402                if(oldchnode != NULL && oldchnode->serviceid == serviceid && oldchnode->transponderid == transponderid)
1403                        chnode = oldchnode;
1404                else
1405                {
1406                        chnode = getchannel(serviceid, transponderid);
1407                        if(chnode == NULL)
1408                        {
1409                                debug(1000, "out -> NULL detect");
1410                                free(title); title = NULL;
1411                                free(subtitle); subtitle = NULL;
1412                                free(desc); desc = NULL;
1413                                continue;
1414                        }
1415                        oldchnode = chnode;
1416                        epgnode = NULL;
1417                }
1418
1419#ifndef SIMULATE
1420                if(endtime < time(NULL) || starttime > time(NULL) + epgmaxsec)
1421                {
1422                        free(title); title = NULL;
1423                        free(subtitle); subtitle = NULL;
1424                        free(desc); desc = NULL;
1425                        continue;
1426                }
1427#endif
1428
1429                epgnode = addepg(chnode, eventid, version, starttime, endtime, epgnode, 1);
1430                if(epgnode == NULL)
1431                {
1432                        debug(1000, "out -> NULL detect");
1433                        free(title); title = NULL;
1434                        free(subtitle); subtitle = NULL;
1435                        free(desc); desc = NULL;
1436                        continue;
1437                }
1438                epgnode->parentalrating = parentalrating;
1439                epgnode->desclen = desclen;
1440                epgnode->desccomplen = desccomplen;
1441                epgnode->title = title;
1442                epgnode->subtitle = subtitle;
1443                epgnode->desc = desc;
1444        }
1445
1446        fclose(fd);
1447
1448        if(getconfigint("epg_del", NULL) == 1)
1449                unlink(filename);
1450               
1451        m_unlock(&status.epgmutex, 4);
1452
1453        debug(1000, "out");
1454        return 0;
1455}
1456
1457//Read EIT segments from DVB-demuxer
1458//flag 0 = end only on channelswitch / or stop sig
1459//flag 1 = end after each run
1460int readeit(struct stimerthread* self, struct channel* chnode, struct dvbdev* fenode, int flag)
1461{
1462        int readlen = 0, pos = 0, len = 0, count = 0;
1463        unsigned char *buf = NULL, *head = NULL;
1464        struct dvbdev* dmxnode;
1465        struct eit* eit = NULL;
1466        unsigned long seen[16] = {0};
1467        unsigned long firstseen[16] = {0};
1468        int roundend = 0, round = 0x4e, i = 0;
1469        time_t akttime, roundstart;
1470
1471        buf = malloc(MINMALLOC * 4);
1472        if(buf == NULL)
1473        {
1474                err("no memory");
1475                return 1;
1476        }
1477        head = buf;
1478
1479        if(fenode == NULL) fenode = status.aktservice->fedev;
1480        if(fenode == NULL)
1481        {
1482                debug(400, "no frontend dev in aktservice");
1483                free(buf);
1484                return 1;
1485        }
1486
1487        dmxnode = dmxopen(fenode);
1488        if(dmxnode == NULL)
1489        {
1490                err("open demux dev");
1491                free(buf);
1492                return 1;
1493        }
1494
1495        dmxsetbuffersize(dmxnode, getconfigint("dmxepgbuffersize", NULL));
1496        dmxsetsource(dmxnode, fenode->fedmxsource);
1497
1498#ifdef SIMULATE
1499        int fd = open("simulate/epg.ts", O_RDONLY);
1500        if(fd == -1)
1501        {
1502                perr("open simulate/epg.ts");
1503                return 1;
1504        }
1505#endif
1506
1507        for(i = 2; i < 16; i++) firstseen[i] = 1;
1508        roundstart = time(NULL);
1509        dmxsetfilter(dmxnode, 0x12, 0, 8);
1510        while(self->aktion != STOP && self->aktion != PAUSE)
1511        {
1512                akttime = time(NULL);
1513                roundend = 1;
1514
1515                //check end of epg infos
1516                for(i = 0; i < 16; i++)
1517                {
1518                        if(roundstart + 5 < akttime && firstseen[i] == 0)
1519                                firstseen[i] = 1;
1520                        if(roundstart + 30 < akttime && firstseen[i] != 1)
1521                                firstseen[i] = 1;
1522                        if(firstseen[i] != 1)
1523                        {
1524                                roundend = 0;
1525                                break;
1526                        }
1527                }
1528               
1529                if(roundend == 1)
1530                {
1531                        for(i = 0; i < 16; i++)
1532                        {
1533                                seen[i] = 0;
1534                                firstseen[i] = 0;
1535                        }
1536
1537                        roundend = 0;
1538                        pos = 0;
1539                        head = buf;
1540
1541                        if(round == 0x60)
1542                        {
1543                                dmxstop(dmxnode);
1544                                if(flag == 1) goto end;
1545                                debug(400, "epg no more new data, wait for next run");
1546                                while(self->aktion != STOP && self->aktion != PAUSE)
1547                                {
1548                                        if(count > 7200) break; //1h
1549                                        count++;
1550                                        usleep(500000);
1551                                }
1552                                count = 0;
1553                                debug(400, "epg next run start");
1554                        }
1555                        if(round == 0x4e)
1556                        {
1557                                dmxsetfilter(dmxnode, 0x12, 0, 6);
1558                                round = 0x50;
1559                        }
1560                        else if(round == 0x50)
1561                        {
1562                                dmxsetfilter(dmxnode, 0x12, 0, 7);
1563                                round = 0x60;
1564                        }
1565                        else if(round == 0x60)
1566                        {
1567                                dmxsetfilter(dmxnode, 0x12, 0, 8);
1568                                for(i = 2; i < 16; i++) firstseen[i] = 1;
1569                                round = 0x4e;
1570                        }
1571                        roundstart = time(NULL);
1572                        continue;
1573                }
1574       
1575                if(pos < 3) goto read_more;
1576
1577                eit = (struct eit*)head;
1578
1579                len = 3 + GETEITSECLEN(eit);
1580                if (pos < len) goto read_more;
1581               
1582                if(eit->table_id - round < 0 || eit->table_id - round > 15 || dvbcrc32((uint8_t *)head, len) != 0)
1583                {
1584                        err("epg crc or table id not ok");
1585                        dmxstop(dmxnode);
1586                        dmxstart(dmxnode);
1587                        pos = 0;
1588                        head = buf;
1589                        goto read_more;
1590                }
1591
1592                seen[eit->table_id - round] = (eit->table_id << 24) | (HILO(eit->service_id) << 8) | eit->section_number;
1593
1594                if(firstseen[eit->table_id - round] == 0)
1595                        firstseen[eit->table_id - round] = seen[eit->table_id - round];
1596                else if(firstseen[eit->table_id - round] == seen[eit->table_id - round])
1597                        firstseen[eit->table_id - round] = 1;
1598
1599                parseeit(chnode, head, len, flag);
1600
1601                //remove packet
1602                pos -= len;
1603                head += len;
1604                continue;
1605read_more:
1606                //clear buffer
1607                if(pos == MINMALLOC * 4)
1608                {
1609                        pos = 0;
1610                        head = buf;
1611                        dmxstop(dmxnode);
1612                        dmxstart(dmxnode);
1613                }
1614
1615                //move remaining data to front of buffer
1616                if (pos > 0) memmove(buf, head, pos);
1617
1618                //del old epg date
1619                if(flag == 0 && status.deloldepg + (5 * 60 * 60) < time(NULL)) // 5 stunde
1620                {
1621                        status.deloldepg = time(NULL);
1622                        deloldepg();
1623                }
1624                //fill with fresh data
1625#ifdef SIMULATE
1626                readlen = TEMP_FAILURE_RETRY(read(fd, buf + pos, (MINMALLOC * 4) - pos));
1627                usleep(200000);
1628#else
1629                readlen = dvbread(dmxnode, buf, pos, (MINMALLOC * 4) - pos, 500000);
1630                usleep(1000);
1631#endif
1632                if(readlen < 0) readlen = 0;
1633                head = buf;
1634                pos += readlen;
1635        }
1636
1637end:
1638#ifdef SIMULATE
1639        close(fd);
1640#endif
1641        dmxclose(dmxnode, -1);
1642        free(buf);
1643        return 0;
1644}
1645
1646void epgthreadfunc(struct stimerthread* self)
1647{
1648        debug(1000, "in");
1649        char* tmpstr = NULL;
1650
1651        //wait for right time
1652        while(self->aktion != STOP && time(NULL) < 1072224000) // 01.01.2004
1653                usleep(1 * 1000000);
1654
1655        debug(400, "start epg thread on aktiv channel");
1656
1657        if(self->notfirst == 0)
1658        {
1659                debug(400, "read epg data from file");
1660                status.deloldepg = time(NULL);
1661                tmpstr = createpath(getconfig("epg_path", NULL), "epg.dat");
1662                readepg(tmpstr);
1663                free(tmpstr); tmpstr = NULL;
1664        }
1665
1666        readeit(self, NULL, NULL, 0);
1667
1668        debug(400, "end epg thread on aktiv channel");
1669        debug(1000, "out");
1670}
1671
1672#endif
Note: See TracBrowser for help on using the repository browser.