source: titan/titan/epg.h @ 10808

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

[titan] optimize epg read funktion

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