source: titan/titan/channel.h @ 38490

Last change on this file since 38490 was 36337, checked in by gost, 8 years ago

fix

File size: 14.8 KB
Line 
1#ifndef CHANNEL_H
2#define CHANNEL_H
3
4void debugchannel()
5{
6        struct channel* node = channel;
7
8        while(node != NULL)
9        {
10                printf("%s %p <%p >%p\n", node->name, node, node->prev, node->next);
11                node = node->next;
12        }
13}
14
15int channelnottunable(struct channel* node)
16{
17        if(node == NULL) return 1;
18        if(node->transponder == NULL) return 1;
19        if(node->transponder->tunablestatus == 0)
20        {
21                if(fegetfree(node->transponder, 1, NULL) == NULL)
22                {
23                        node->transponder->tunablestatus = 2;
24                        return 1;
25                }
26                else
27                {
28                        node->transponder->tunablestatus = 1;
29                        return 0;
30                }
31        }
32        else if(node->transponder->tunablestatus == 2)
33                return 1;
34
35        return 0;
36}
37
38//flag 0: lock
39//flag 1: no lock
40struct channel* getlastchannel(struct channel* node, int flag)
41{
42        struct channel *prev = NULL;
43
44        if(flag == 0) m_lock(&status.channelmutex, 5);
45        while(node != NULL)
46        {
47                prev = node;
48                node = node->next;
49        }
50        if(flag == 0) m_unlock(&status.channelmutex, 5);
51
52        return prev;
53}
54
55struct channel* gettmpchannel()
56{
57        m_lock(&status.channelmutex, 5);
58  struct channel *node = channel;
59 
60        while(node != NULL)
61        {
62                if(node->servicetype == 99)
63                        break;
64                node = node->next;
65        }
66        m_unlock(&status.channelmutex, 5);
67
68        return node;
69}
70
71struct channel* getprevchannelbyservicetype(struct channel* node)
72{
73        struct channel* prev = NULL;
74
75        if(node == NULL) node = channel;
76        if(node == NULL) return NULL;
77
78        prev = node->prev;
79        while(prev != NULL && prev->servicetype != status.servicetype)
80                prev = prev->prev;
81        if(prev == NULL)
82        {
83                prev = getlastchannel(channel, 0);
84                while(prev != NULL && prev->servicetype != status.servicetype)
85                        prev = prev->prev;
86        }
87
88        return prev;
89}
90
91struct channel* getnextchannelbyservicetype(struct channel* node)
92{
93        struct channel* next = NULL;
94
95        if(node == NULL) node = channel;
96        if(node == NULL) return NULL;
97
98        next = node->next;
99
100        while(next != NULL && next->servicetype != status.servicetype)
101                next = next->next;
102        if(next == NULL)
103        {
104                next = channel;
105                while(next != NULL && next->servicetype != status.servicetype)
106                        next = next->next;
107        }
108
109        return next;
110}
111
112int movechannelblockdown(struct channel* node)
113{
114        int i = 0, ret = 0;
115        struct channel* prev = NULL;
116
117        if(node == NULL || channel == NULL) return 1;
118
119        for(i = 0; i < status.moveblockcount; i++)
120        {
121                if(node == NULL) break;
122                node = node->next;
123                while(node != NULL && node->servicetype != status.servicetype)
124                        node = node->next;
125        }
126
127        for(i = 0; i < status.moveblockcount + 1; i++)
128        {
129                if(node == NULL) break;
130                prev = getprevchannelbyservicetype(node);
131                ret = movechanneldown(node);
132
133                while(node->prev != NULL && node->prev->servicetype != status.servicetype)
134                        ret = movechanneldown(node);
135
136                node = prev;
137        }
138
139        return ret;
140}
141
142int movechanneldown(struct channel* node)
143{
144        struct channel* prev = NULL, *next = NULL;
145
146        if(node == NULL || channel == NULL) return 1;
147
148        m_lock(&status.channelmutex, 5);
149
150        //last node
151        if(node->next == NULL)
152        {
153                if(node->prev != NULL)
154                        node->prev->next = NULL;
155                node->prev = NULL;
156                node->next = channel;
157                channel->prev = node;
158                channel = node;
159                m_unlock(&status.channelmutex, 5);
160                return 99;
161        }
162
163        //haenge node aus
164        if(node->prev != NULL)
165                node->prev->next = node->next;
166        else
167                channel = node->next;
168        node->next->prev = node->prev;
169
170        //save nodes next and prev
171        next = node->next;
172        prev = node->prev;
173
174        //haenge es eine pos nacher ein
175        node->next = next->next;
176        node->prev = next;
177       
178        if(next->next != NULL)
179                next->next->prev = node;
180        next->next = node;
181
182        m_unlock(&status.channelmutex, 5);
183
184        status.writechannel = 1;
185        return 0;
186}
187
188int movechannelblockup(struct channel* node)
189{
190        int i = 0, ret = 0;
191        struct channel* next = NULL;
192
193        if(node == NULL || channel == NULL) return 1;
194
195        for(i = 0; i < status.moveblockcount + 1; i++)
196        {
197                if(node == NULL) break;
198                next = getnextchannelbyservicetype(node);
199                ret = movechannelup(node);
200
201                while(node->next != NULL && node->next->servicetype != status.servicetype)
202                        ret = movechannelup(node);
203
204                node = next;
205        }
206
207        return ret;
208}
209
210int movechannelup(struct channel* node)
211{
212        struct channel* prev = NULL, *next = NULL, *last = NULL;
213
214        if(node == NULL || channel == NULL) return 1;
215
216        m_lock(&status.channelmutex, 5);
217
218        //first node
219        if(node->prev == NULL)
220        {
221                last = getlastchannel(channel, 1);
222
223                if(node->next != NULL)
224                        node->next->prev = NULL;
225                channel = node->next;
226                node->next = NULL;
227                last->next = node;
228                node->prev = last;
229                m_unlock(&status.channelmutex, 5);
230                return 99;
231        }
232
233        //haenge node aus
234        node->prev->next = node->next;
235        if(node->next != NULL)
236                node->next->prev = node->prev;
237
238        //save nodes next and prev
239        next = node->next;
240        prev = node->prev;
241
242        //haenge es eine pos voher ein
243        node->next = prev;
244        node->prev = prev->prev;
245       
246        if(prev->prev != NULL)
247                prev->prev->next = node;
248        else
249                channel = node;
250        prev->prev = node;
251
252        m_unlock(&status.channelmutex, 5);
253
254        status.writechannel = 1;
255        return 0;
256}
257
258struct channel* addchannel(char *line, int count, struct channel* last)
259{
260        struct channel *newnode = NULL, *prev = NULL, *node = NULL;
261        char *name = NULL;
262        int ret = 0;
263
264        if(line == NULL) return NULL;
265
266        newnode = (struct channel*)calloc(1, sizeof(struct channel));
267        if(newnode == NULL)
268        {
269                err("no memory");
270                return NULL;
271        }
272
273        name = malloc(MINMALLOC);
274        if(name == NULL)
275        {
276                err("no memory");
277                free(newnode);
278                return NULL;
279        }
280
281  ret = sscanf(line, "%[^#]#%llu#%d#%d#%d#%"SCNu8"#%"SCNu8"#%"SCNu8"#%"SCNu16"#%"SCNu16"#%"SCNu8"#%"SCNu16, name, &newnode->transponderid, &newnode->providerid, &newnode->serviceid, &newnode->servicetype, &newnode->flag, &newnode->videocodec, &newnode->audiocodec, &newnode->videopid, &newnode->audiopid, &newnode->protect, &newnode->pcrpid);
282        if(ret == 11)
283        {
284                newnode->pcrpid = -1;
285                ret++; 
286        }
287        if(ret != 12 || getchannel(newnode->serviceid, newnode->transponderid) != NULL)
288        {
289                if(count > 0)
290                {
291                        err("channellist line %d not ok or double", count);
292                }
293                else
294                {
295                        err("add channel");
296                }
297                free(name);
298                free(newnode);
299                return NULL;
300        }
301
302        newnode->name = ostrshrink(name);
303        //99 = tmp channel
304        if(newnode->servicetype != 99)
305        {
306                newnode->transponder = gettransponder(newnode->transponderid);
307                newnode->provider = getprovider(newnode->providerid);
308                status.writechannel = 1;
309        }
310
311        m_lock(&status.channelmutex, 5);
312        node = channel;
313
314        modifychannelcache(newnode->serviceid, newnode->transponderid, newnode);
315
316        if(last == NULL)
317        {
318                while(node != NULL && strcasecmp(newnode->name, node->name) > 0)
319                {
320                        prev = node;
321                        node = node->next;
322                }
323        }
324        else
325        {
326                prev = last;
327                node = last->next;
328        }
329
330        if(prev == NULL)
331                channel = newnode;
332        else
333        {
334                prev->next = newnode;
335                newnode->prev = prev;
336        }
337        newnode->next = node;
338        if(node != NULL) node->prev = newnode;
339       
340        m_unlock(&status.channelmutex, 5);
341        return newnode;
342}
343
344struct channel* createchannel(char* name, uint64_t transponderid, int providerid, int serviceid, int servicetype, int flag, int videocodec, int audiocodec, int videopid, int audiopid, int protect, int pcrpid)
345{
346        struct channel* chnode = NULL;
347        char* tmpstr = NULL;
348
349        tmpstr = ostrcat(tmpstr, name, 1, 0);
350        tmpstr = ostrcat(tmpstr, "#", 1, 0);
351        tmpstr = ostrcat(tmpstr, ollutoa(transponderid), 1, 1);
352        tmpstr = ostrcat(tmpstr, "#", 1, 0);
353        tmpstr = ostrcat(tmpstr, oitoa(providerid), 1, 1);
354        tmpstr = ostrcat(tmpstr, "#", 1, 0);
355        tmpstr = ostrcat(tmpstr, oitoa(serviceid), 1, 1);
356        tmpstr = ostrcat(tmpstr, "#", 1, 0);
357        tmpstr = ostrcat(tmpstr, oitoa(servicetype), 1, 1);
358        tmpstr = ostrcat(tmpstr, "#", 1, 0);
359        tmpstr = ostrcat(tmpstr, oitoa(flag), 1, 1);
360        tmpstr = ostrcat(tmpstr, "#", 1, 0);
361        tmpstr = ostrcat(tmpstr, oitoa(videocodec), 1, 1);
362        tmpstr = ostrcat(tmpstr, "#", 1, 0);
363        tmpstr = ostrcat(tmpstr, oitoa(audiocodec), 1, 1);
364        tmpstr = ostrcat(tmpstr, "#", 1, 0);
365        tmpstr = ostrcat(tmpstr, oitoa(videopid), 1, 1);
366        tmpstr = ostrcat(tmpstr, "#", 1, 0);
367        tmpstr = ostrcat(tmpstr, oitoa(audiopid), 1, 1);
368        tmpstr = ostrcat(tmpstr, "#", 1, 0);
369        tmpstr = ostrcat(tmpstr, oitoa(protect), 1, 1);
370        tmpstr = ostrcat(tmpstr, "#", 1, 0);
371        tmpstr = ostrcat(tmpstr, oitoa(pcrpid), 1, 1);
372
373        chnode = addchannel(tmpstr, 1, NULL);
374
375        free(tmpstr);
376        return chnode;
377}
378
379int readchannel(const char* filename)
380{
381        FILE *fd = NULL;
382        char *fileline = NULL;
383        int linecount = 0, len = 0;
384        struct channel* last = NULL, *tmplast = NULL;
385
386        fileline = malloc(MINMALLOC);
387        if(fileline == NULL)
388        {
389                err("no memory");
390                return 1;
391        }
392
393        fd = fopen(filename, "r");
394        if(fd == NULL)
395        {
396                perr("can't open %s", filename);
397                free(fileline);
398                return 1;
399        }
400
401        while(fgets(fileline, MINMALLOC, fd) != NULL)
402        {
403                if(fileline[0] == '#' || fileline[0] == '\n')
404                        continue;
405                len = strlen(fileline) - 1;
406                if(len >= 0 && fileline[len] == '\n')
407                        fileline[len] = '\0';
408                len--;
409                if(len >= 0 && fileline[len] == '\r')
410                        fileline[len] = '\0';
411
412                linecount++;
413
414                if(last == NULL) last = tmplast;
415                last = addchannel(fileline, linecount, last);
416                if(last != NULL) tmplast = last;
417        }
418
419        status.writechannel = 0;
420        free(fileline);
421        fclose(fd);
422        return 0;
423}
424
425//flag 0: del bouquet
426//flag 1: don't del bouquet
427int delchannel(int serviceid, uint64_t transponderid, int flag)
428{
429        int ret = 1;
430        struct provider* providernode = NULL;
431
432        m_lock(&status.channelmutex, 5);
433  struct channel *node = channel, *prev = channel;
434
435        while(node != NULL)
436        {
437                if(node->serviceid == serviceid && node->transponderid == transponderid && getservicebychannel(node) == NULL)
438                {
439                        ret = 0;
440                        if(node->servicetype != 99) status.writechannel = 1;
441                        if(node == channel)
442                        {
443                                channel = node->next;
444                                if(channel != NULL)
445                                        channel->prev = NULL;
446                        }
447                        else
448                        {
449                                prev->next = node->next;
450                                if(node->next != NULL)
451                                        node->next->prev = prev;
452                        }
453
454                        if(flag == 0)
455                        {
456                                delbouquetbychannel(node->serviceid, node->transponderid);
457                                delepgscanlist(node->serviceid, node->transponderid);
458                        }
459                        else
460                                setbouquetchanneltonullmain(node->serviceid, node->transponderid);
461
462                        providernode = node->provider;
463                        delchannelcache(node->serviceid, node->transponderid);
464                        delchannelhistory(node);
465                        delmostzap(node->serviceid, node->transponderid, 0);
466
467                        freeaudiotrack(node);
468                        free(node->audiotrack);
469                        node->audiotrack = NULL;
470
471                        freesubtitle(node);
472                        free(node->subtitle);
473                        node->subtitle = NULL;
474                       
475                        freelinkedchannel(node);
476                        free(node->linkedchannel);
477                        node->linkedchannel = NULL;
478
479                        freepmt(node);
480                        free(node->pmt);
481                        node->pmt = NULL;
482
483                        freecadesc(node);
484                        free(node->cadesc);
485                        node->cadesc = NULL;
486
487                        freeesinfo(node);
488                        free(node->esinfo);
489                        node->esinfo = NULL;
490
491                        freeepg(node);
492                        node->epg = NULL;
493
494                        free(node->name);
495                        node->name = NULL;
496     
497      free(node->hbbtvurl);
498      node->hbbtvurl = NULL;
499
500                        free(node);
501                        node = NULL;
502
503                        delprovidernotused(providernode);
504                        break;
505                }
506
507                prev = node;
508                node = node->next;
509        }
510
511        recalcbouquetnr();
512        m_unlock(&status.channelmutex, 5);
513        return ret;
514}
515
516void delchannelbytransponder(uint64_t transponderid)
517{
518        struct channel *node = channel, *prev = channel;
519
520        while(node != NULL)
521        {
522                prev = node;
523                node = node->next;
524                if(prev != NULL && prev->transponderid == transponderid)
525                        delchannel(prev->serviceid, prev->transponderid, 0);
526        }
527}
528
529//flag 0: del bouquet
530//flag 1: don't del bouquet
531void freechannel(int flag)
532{
533        struct channel *node = channel, *prev = channel;
534
535        while(node != NULL)
536        {
537                prev = node;
538                node = node->next;
539                if(prev != NULL)
540                        delchannel(prev->serviceid, prev->transponderid, flag);
541        }
542}
543
544/*
545struct channel* sortchannel()
546{
547        struct channel *node = channel;
548        struct channel *nodea = NULL, *nodeb = NULL, *nodec = NULL, *noded = NULL;
549        struct channel *nodetmp = NULL;
550
551        if(node == NULL) return NULL;
552       
553        struct channel **nodeaddr = &channel;
554
555        if(node != NULL)
556        {
557                while(noded != node->next)
558                {
559                        nodec = node;
560                        nodea = node;
561                        nodeb = nodea->next;
562
563                        while(nodea != noded)
564                        {
565                                if(strcasecmp(nodea->name, nodeb->name) > 0)
566                                {
567                                        if(nodea == node)
568                                        {
569                                                nodetmp = nodeb->next;
570                                                nodeb->next = nodea;
571                                                nodea->next = nodetmp;
572                                                node = nodeb;
573                                                *nodeaddr = nodeb;
574                                                nodec = nodeb;
575                                        }
576                                        else
577                                        {
578                                                nodetmp = nodeb->next;
579                                                nodeb->next = nodea;
580                                                nodea->next = nodetmp;
581                                                nodec->next = nodeb;
582                                                nodec = nodeb;
583                                        }
584                                }
585                                else
586                                {
587                                        nodec = nodea;
588                                        nodea = nodea->next;
589                                }
590                                nodeb = nodea->next;
591                                if (nodeb == noded)
592                                        noded = nodea;
593                        }
594                }
595        }
596
597        //calc prev
598        struct channel* prev = NULL;
599        nodetmp = node;
600        while(nodetmp != NULL)
601        {
602                nodetmp->prev = prev;
603                prev = nodetmp;
604
605                nodetmp = nodetmp->next;
606        }
607
608        status.writechannel = 1;
609        return channel;
610}
611*/
612
613struct channel* sortchannel()
614{
615        struct channel* tmpnode[10] = {0};
616        struct channel* node = channel, *tnode = NULL;
617        struct channel *next = NULL, *prev = NULL;
618        struct channel **tnodeaddr = NULL;
619       
620        if(node == NULL) return NULL;
621
622        while(node != NULL)
623        {
624                next = node->next;
625                prev = NULL;
626
627                if(strcasecmp("c", node->name) > 0) {tnode = tmpnode[0]; tnodeaddr = &tmpnode[0];}
628                else if(strcasecmp("f", node->name) > 0) {tnode = tmpnode[1]; tnodeaddr = &tmpnode[1];}
629                else if(strcasecmp("i", node->name) > 0) {tnode = tmpnode[2]; tnodeaddr = &tmpnode[2];}
630                else if(strcasecmp("l", node->name) > 0) {tnode = tmpnode[3]; tnodeaddr = &tmpnode[3];}
631                else if(strcasecmp("o", node->name) > 0) {tnode = tmpnode[4]; tnodeaddr = &tmpnode[4];}
632                else if(strcasecmp("r", node->name) > 0) {tnode = tmpnode[5]; tnodeaddr = &tmpnode[5];}
633                else if(strcasecmp("u", node->name) > 0) {tnode = tmpnode[6]; tnodeaddr = &tmpnode[6];}
634                else if(strcasecmp("x", node->name) > 0) {tnode = tmpnode[7]; tnodeaddr = &tmpnode[7];}
635                else if(strcasecmp("z", node->name) > 0) {tnode = tmpnode[8]; tnodeaddr = &tmpnode[8];}
636                else {tnode = tmpnode[9]; tnodeaddr = &tmpnode[9];}
637
638                while(tnode != NULL && strcasecmp(node->name, tnode->name) > 0)
639                {
640                        prev = tnode;
641                        tnode = tnode->next;
642                }
643
644                if(prev == NULL)
645                {
646                        *tnodeaddr = node;
647                        node->prev = NULL;
648                }
649                else
650                {
651                        prev->next = node;
652                        node->prev = prev;
653                }
654                node->next = tnode;
655                if(tnode != NULL) tnode->prev = node;
656
657                node = next;
658        }
659
660        int i = 0, first = 0;
661        prev = NULL; node = NULL;
662        for(i = 0; i < 10; i++)
663        {
664                if(tmpnode[i] != NULL)
665                {
666                        if(prev != NULL)
667                        {
668                                prev->next = tmpnode[i];
669                                tmpnode[i]->prev = prev;
670                        }
671
672                        if(first == 0)
673                        {
674                                channel = tmpnode[i];
675                                first = 1;
676                        }
677
678                        node = tmpnode[i];
679                        while(node != NULL)
680                        {
681                                prev = node;
682                                node = node->next;
683                        }
684                }
685        }
686
687        status.writechannel = 1;
688        return channel;
689}
690
691int writechannel(const char *filename)
692{
693        FILE *fd = NULL;
694        struct channel *node = NULL;
695        int ret = 0;
696
697        fd = fopen(filename, "w");
698        if(fd == NULL)
699        {
700                perr("can't open %s", filename);
701                return 1;
702        }
703
704        m_lock(&status.channelmutex, 5);
705        node = channel;
706
707        while(node != NULL)
708        {
709                if(node->servicetype == 99)
710                {
711                        node = node->next;
712                        continue;
713                }
714                ret = fprintf(fd, "%s#%llu#%d#%d#%d#%d#%d#%d#%d#%d#%d#%d\n", node->name, node->transponderid, node->providerid, node->serviceid, node->servicetype, node->flag, node->videocodec, node->audiocodec, node->videopid, node->audiopid, node->protect, node->pcrpid);
715                if(ret < 0)
716                {
717                        perr("writting file %s", filename);
718                }
719                node = node->next;
720        }
721        m_unlock(&status.channelmutex, 5);
722
723        fclose(fd);
724        return 0;
725}
726
727#endif
Note: See TracBrowser for help on using the repository browser.