source: titan/titan/frontenddev.h @ 41156

Last change on this file since 41156 was 41156, checked in by gost, 6 years ago

[titan] frontenddev cleaned up

File size: 61.0 KB
Line 
1#ifndef FRONTENDDEV_H
2#define FRONTENDDEV_H
3
4enum {
5                T_Bandwidth_8MHz, T_Bandwidth_7MHz, T_Bandwidth_6MHz, T_Bandwidth_Auto, T_Bandwidth_5MHz, T_Bandwidth_1_712MHz, T_Bandwidth_10MHz
6};
7
8enum {
9                T_FEC_1_2=0, T_FEC_2_3=1, T_FEC_3_4=2, T_FEC_5_6=3, T_FEC_7_8=4, T_FEC_Auto=5, T_FEC_6_7=6, T_FEC_8_9=7
10};
11
12enum {
13                System_DVB_T_T2 = -1, System_DVB_T, System_DVB_T2
14};
15
16enum {
17                T_TransmissionMode_2k, T_TransmissionMode_8k, T_TransmissionMode_Auto, T_TransmissionMode_4k, T_TransmissionMode_1k, T_TransmissionMode_16k, T_TransmissionMode_32k
18};
19
20enum {
21                T_GuardInterval_1_32, T_GuardInterval_1_16, T_GuardInterval_1_8, T_GuardInterval_1_4, T_GuardInterval_Auto, T_GuardInterval_1_128, T_GuardInterval_19_128, T_GuardInterval_19_256
22};
23
24enum {
25                T_Hierarchy_None, T_Hierarchy_1, T_Hierarchy_2, T_Hierarchy_4, T_Hierarchy_Auto
26};
27
28enum {
29                T_Modulation_QPSK, T_Modulation_QAM16, T_Modulation_QAM64, T_Modulation_Auto, T_Modulation_QAM256
30};
31
32enum {
33                T_Inversion_Off, T_Inversion_On, T_Inversion_Unknown
34};
35
36int calclof(struct dvbdev* node, struct transponder* tpnode, char* feaktnr, int flag)
37{
38        int loftype = 0;
39        int lofl, lofh, lofthreshold;
40        int satcrfrequ = 0;
41        char* tmpstr = NULL;
42
43        if(node == NULL || tpnode == NULL)
44        {
45                err("NULL detect");
46                return -1;
47        }
48
49        if(node->feinfo->type != FE_QPSK)
50                return 0;
51
52        unsigned int frequency = tpnode->frequency;
53        node->feunicable = 0;
54
55        if(feaktnr == NULL) feaktnr = node->feaktnr;
56
57        tmpstr = ostrcat(node->feshortname, "_lnb_loftype", 0, 0);
58        loftype = getconfigint(tmpstr, feaktnr);
59        free(tmpstr); tmpstr = NULL;
60        switch(loftype)
61        {
62                case 1: //c-band
63                        lofl = 5150 * 1000;
64                        lofh = 5150 * 1000;
65                        lofthreshold = 5150 * 1000;
66                        break;
67                case 2: //user
68                        tmpstr = ostrcat(node->feshortname, "_lnb_lofl", 0, 0);
69                        lofl = getconfigint(tmpstr, feaktnr) * 1000;
70                        free(tmpstr); tmpstr = NULL;
71                        tmpstr = ostrcat(node->feshortname, "_lnb_lofh", 0, 0);
72                        lofh = getconfigint(tmpstr, feaktnr) * 1000;
73                        free(tmpstr); tmpstr = NULL;
74                        tmpstr = ostrcat(node->feshortname, "_lnb_lofthreshold", 0, 0);
75                        lofthreshold = getconfigint(tmpstr, feaktnr) * 1000;
76                        free(tmpstr); tmpstr = NULL;
77                        break;
78                case 3: //unicable
79                case 4: //user unicable
80                        tmpstr = ostrcat(node->feshortname, "_lnb_lofl", 0, 0);
81                        lofl = getconfigint(tmpstr, feaktnr) * 1000;
82                        free(tmpstr); tmpstr = NULL;
83                        if(lofl == 0) lofl = 9750 * 1000;
84                        tmpstr = ostrcat(node->feshortname, "_lnb_lofh", 0, 0);
85                        lofh = getconfigint(tmpstr, feaktnr) * 1000;
86                        free(tmpstr); tmpstr = NULL;
87                        if(lofh == 0) lofh = 10600 * 1000;
88                        tmpstr = ostrcat(node->feshortname, "_lnb_lofthreshold", 0, 0);
89                        lofthreshold = getconfigint(tmpstr, feaktnr) * 1000;
90                        free(tmpstr); tmpstr = NULL;
91                        if(lofthreshold == 0) lofthreshold = 11700 * 1000;
92                        tmpstr = ostrcat(node->feshortname, "_lnb_satcrfrequ", 0, 0);
93                        satcrfrequ = getconfigint(tmpstr, feaktnr) * 1000;
94                        free(tmpstr); tmpstr = NULL;
95                        break;
96                default: //standard lnb
97                        lofl = 9750 * 1000;
98                        lofh = 10600 * 1000;
99                        lofthreshold = 11700 * 1000;
100        }
101
102        if(lofthreshold && lofh && frequency >= lofthreshold)
103        {
104                if(flag == 1) return 1;
105                node->feaktband = 1;
106        }
107        else
108        {
109                if(flag == 1) return 0;
110                node->feaktband = 0;
111        }
112
113        if(satcrfrequ == 0)
114        {
115                if(node->feaktband)
116                        node->feloffrequency = frequency - lofh;
117                else
118                {
119                        if(frequency < lofl)
120                                node->feloffrequency = lofl - frequency;
121                        else
122                                node->feloffrequency = frequency - lofl;
123                }
124        }
125        else
126        {
127                int lof = (node->feaktband & 1) ? lofh : lofl;
128                unsigned int tmp = (frequency - lof) + satcrfrequ;
129                node->feloffrequency = (tmp / 4) - 350000;
130                node->feunicable = 1;
131        }
132
133        debug(200, "tuning to freq %d (befor lof %d), band=%d, unicable=%d", node->feloffrequency, frequency, node->feaktband, node->feunicable);
134        return node->feaktband;
135}
136
137char* fegettypestr(struct dvbdev* dvbnode)
138{
139        char* text = NULL;
140
141        if(dvbnode == NULL)
142        {
143                err("NULL detect");
144                return NULL;
145        }
146
147        switch(dvbnode->feinfo->type)
148        {
149                case FE_QPSK: text = ostrcat(text, "DVB-S", 1, 0); break;
150                case FE_QAM: text = ostrcat(text, "DVB-C", 1, 0); break;
151                case FE_OFDM: text = ostrcat(text, "DVB-T", 1, 0); break;
152                default: text = ostrcat(text, "unknown", 1, 0);
153        }
154
155        return text;
156}
157
158struct dvbdev* fegetbyshortname(char* feshortname)
159{
160        struct dvbdev* dvbnode = dvbdev;
161       
162        while(dvbnode != NULL)
163        {
164                if(dvbnode->type == FRONTENDDEV && ostrcmp(dvbnode->feshortname, feshortname) == 0)
165                        return dvbnode;
166                dvbnode = dvbnode->next;
167        }
168        return NULL;
169}
170
171void fegetconfig(struct dvbdev *dvbnode, struct transponder *tpnode, char** aktnr, char* tmpnr)
172{
173        char* tmpstr = NULL;
174
175        if(dvbnode == NULL || tpnode == NULL)
176        {
177                err("NULL detect");
178                return;
179        }
180
181        tmpstr = ostrcat(dvbnode->feshortname, "_satnr", 0, 0);
182        *aktnr = getconfig(tmpstr, tmpnr);
183        free(tmpstr); tmpstr = NULL;
184}
185
186struct dvbdev* fegetdummy()
187{
188        struct dvbdev* dvbnode = dvbdev;
189
190        while(dvbnode != NULL)
191        {
192                if(dvbnode->type == FRONTENDDEVDUMMY)
193                        return dvbnode;
194                dvbnode = dvbnode->next;
195        }
196        return NULL;
197}
198
199void settunerstatus()
200{
201        struct dvbdev* dvbnode = dvbdev;
202        char *tmpstr = NULL;
203        char *buf = NULL;
204        int fbc = 0;
205        while(dvbnode != NULL)
206        {
207                //FRONTENDDEV first in the list
208                if(dvbnode->type != FRONTENDDEV) break;
209               
210                if(dvbnode != NULL && ostrstr(dvbnode->feinfo->name, "BCM45208") != NULL)
211                        fbc = 1;
212                else
213                        fbc = 0;
214
215                if((checkbox("DM900") == 1 || checkbox("DM520") == 1 || checkbox("DM525") == 1) && fbc != 1)
216                {
217                        if(ostrcmp("fe_01", dvbnode->feshortname) == 0)
218                        {
219                                if(ostrcmp("fe_00", getconfig(dvbnode->feshortname, NULL)) == 0)
220                                        system("echo internal > /proc/stb/frontend/1/rf_switch");
221                                else
222                                        system("echo external > /proc/stb/frontend/1/rf_switch");
223                        }
224                }
225                if(fbc == 1)
226                {
227                        buf = malloc(MINMALLOC);
228                        if(buf == NULL)
229                        {
230                                err("no memory");
231                                return;
232                        }
233                        sprintf(buf, "/proc/stb/frontend/%d/input",dvbnode->devnr);
234                        tmpstr = ostrcat(dvbnode->feshortname, "_fbc", 0, 0);
235                        if(ostrcmp("AM", getconfig(tmpstr, NULL)) == 0 || ostrcmp("AU", getconfig(tmpstr, NULL)) == 0 || ostrcmp("A", getconfig(tmpstr, NULL)) == 0)
236                                writesys(buf, "A", 1);
237                        else
238                                writesys(buf, "B", 1); 
239                        free(buf); buf = NULL;
240                        free(tmpstr); tmpstr = NULL;
241                }
242                //check if tuner is deactivate
243                if(ostrcmp("x", getconfig(dvbnode->feshortname, NULL)) == 0)
244                        dvbnode->deactive = 1;
245                else
246                        dvbnode->deactive = 0;
247
248                dvbnode = dvbnode->next;
249        }
250}
251
252//flag 0 = normal
253//flag 1 = check only
254//flag 2 = from record
255//flag 3 = from rectimer
256struct dvbdev* fegetfree(struct transponder* tpnode, int flag, struct dvbdev* dvbfirst)
257{
258        struct dvbdev* dvbnode = NULL;
259        struct dvbdev* tmpdvbnode = NULL;
260        char* tmpstr = NULL, *tmpnr = NULL, *aktnr = NULL;
261        int i, orbitalpos = 0, band = 0;
262        int found = 0;
263        //char *CharPtrTmp[20];
264        struct dvbdev* CharPtrTmp[20];
265       
266        if(dvbfirst != NULL)
267                dvbnode = dvbfirst;
268        else
269                dvbnode = dvbdev;
270
271        if(tpnode == NULL)
272        {
273                err("NULL detect");
274                return NULL;
275        }
276
277        //suche tuner der auf der gleichen orbitalpos/frequency/pol/band ist
278        while(dvbnode != NULL)
279        {
280                //FRONTENDDEV first in the list
281                if(dvbnode->type != FRONTENDDEV) break;
282
283                //check if tuner is deactivate
284                if(dvbnode->deactive == 1)
285                {
286                        dvbnode = dvbnode->next;
287                        continue;
288                }
289                if(dvbnode->type == FRONTENDDEV && dvbnode->feinfo->type == tpnode->fetype)
290                {
291                        if(dvbnode->feakttransponder != NULL && dvbnode->felock == 0 && status.aktservice->fedev != dvbnode)
292                        {
293                                if(flag != 1) debug(200, "clear tuner %s", dvbnode->feshortname);
294                                dvbnode->feakttransponder = NULL;
295                        }       
296                        if(dvbnode->feakttransponder != NULL && dvbnode->feakttransponder->orbitalpos == tpnode->orbitalpos && dvbnode->feakttransponder->frequency == tpnode->frequency && dvbnode->feaktpolarization == tpnode->polarization)
297                        {
298                                band = calclof(dvbnode, tpnode, dvbnode->feaktnr, 1);
299                                if(dvbnode->feaktband != band)
300                                {
301                                        dvbnode = dvbnode->next;
302                                        continue;
303                                }
304                                dvbnode->felasttransponder = dvbnode->feakttransponder;
305                                dvbnode->feakttransponder = tpnode;
306                                if(flag != 1) debug(200, "found tuner with same orbitalpos/frequency/pol/band %s", dvbnode->feshortname);
307                                return(dvbnode);
308                        }
309                }
310                dvbnode = dvbnode->next;
311        }
312        if(dvbfirst != NULL)
313                dvbnode = dvbfirst;
314        else
315                dvbnode = dvbdev;
316
317        //suche tuner der die gewuenschte orbitalpos kann und belegt ist und dessen looptuner es kann
318        while(dvbnode != NULL)
319        {
320                //FRONTENDDEV first in the list
321                if(dvbnode->type != FRONTENDDEV) break;
322
323                //check if tuner is deactivate
324                if(dvbnode->deactive == 1)
325                {
326                        dvbnode = dvbnode->next;
327                        continue;
328                }
329                if(dvbnode->type == FRONTENDDEV && dvbnode->feinfo->type == tpnode->fetype && (dvbnode->felock != 0 || (flag == 2 && status.aktservice->fedev == dvbnode)))
330                {
331                        //check if tuner is main tuner
332                        if(getconfig(dvbnode->feshortname, NULL) != NULL)
333                        {
334                                dvbnode = dvbnode->next;
335                                continue;                               
336                        }
337                        if(dvbnode->feaktpolarization != tpnode->polarization || dvbnode->feakttransponder->orbitalpos != tpnode->orbitalpos)
338                        {
339                                dvbnode = dvbnode->next;
340                                continue;                               
341                        }
342                        found = 0;
343                        //check looptuner is free
344                        tmpstr = getconfigbyval(dvbnode->feshortname, NULL);
345                        CharPtrTmp[0] = NULL;
346                        while(tmpstr != NULL) //found loop tuner
347                        {
348                                tmpdvbnode = fegetbyshortname(tmpstr);
349                                if(tmpdvbnode != NULL)
350                                {
351                                        if(tmpdvbnode->feakttransponder == NULL || (tmpdvbnode->felock == 0 && status.aktservice->fedev != tmpdvbnode))
352                                        {
353                                                found = 99;
354                                                break;
355                                        }
356                                        else
357                                        {
358                                                CharPtrTmp[found] = tmpdvbnode;
359                                                found = found + 1;
360                                        }
361                                }
362                                tmpstr = getconfigbyval(tmpstr, NULL); //loop tuner also loop  ?
363                        }
364                        CharPtrTmp[0] = NULL;
365                        if(found != 99)
366                        {
367                                dvbnode = dvbnode->next;
368                                continue;
369                        }
370                        tmpstr = ostrcat(dvbnode->feshortname, "_sat", 0, 0);
371                        for(i = 1; i <= getmaxsat(dvbnode->feshortname); i++)
372                        {
373                                tmpnr = oitoa(i);
374                                orbitalpos = getconfigint(tmpstr, tmpnr);
375                                if(orbitalpos == tpnode->orbitalpos)
376                                {
377                                        fegetconfig(dvbnode, tpnode, &aktnr, tmpnr);
378                                        if(flag == 3)
379                                                band = calclof(dvbnode, tpnode, aktnr, 0);
380                                        else
381                                                band = calclof(dvbnode, tpnode, aktnr, 1);
382                                        found = 0;
383                                        if(dvbnode->feaktband != band)
384                                        {
385                                                found = -1;
386                                                break;
387                                        }
388                                        if(flag == 1)
389                                        {
390                                                free(tmpstr); tmpstr = NULL;
391                                                free(tmpnr); tmpnr = NULL;
392                                                return tmpdvbnode;
393                                        }
394                                        if(tmpdvbnode->feakttransponder != NULL)
395                                                tmpdvbnode->felasttransponder = tmpdvbnode->feakttransponder;
396                                        tmpdvbnode->feakttransponder = tpnode;
397                                        tmpdvbnode->feaktpolarization = tpnode->polarization;
398                                        tmpdvbnode->feaktband = band;
399                                        free(tmpdvbnode->feaktnr);
400                                        if(aktnr != NULL)
401                                                tmpdvbnode->feaktnr = ostrcat(aktnr, NULL, 0, 0);
402                                        else
403                                                tmpdvbnode->feaktnr = NULL;
404
405                                        free(tmpstr); tmpstr = NULL;
406                                        free(tmpnr); tmpnr = NULL;
407                                        if(flag != 1) debug(200, "found free tuner witch same orbitalpos %s", dvbnode->feshortname);
408                                        return tmpdvbnode;
409                                }
410                                free(tmpnr); tmpnr = NULL;
411                        }
412                        free(tmpstr); tmpstr = NULL;
413                }
414                dvbnode = dvbnode->next;
415        }
416        if(dvbfirst != NULL)
417                dvbnode = dvbfirst;
418        else
419                dvbnode = dvbdev;
420
421        //suche tuner der die gewuenschte orbitalpos kann und nicht belegt ist
422        while(dvbnode != NULL)
423        {
424                //FRONTENDDEV first in the list
425                if(dvbnode->type != FRONTENDDEV) break;
426
427                //check if tuner is deactivate
428                if(dvbnode->deactive == 1)
429                {
430                        dvbnode = dvbnode->next;
431                        continue;
432                }
433                if(dvbnode->type == FRONTENDDEV && dvbnode->feinfo->type == tpnode->fetype && dvbnode->felock == 0)
434                {
435                        //check if tuner is main tuner
436                        if(getconfig(dvbnode->feshortname, NULL) != NULL)
437                        {
438                                dvbnode = dvbnode->next;
439                                continue;                               
440                        }
441                        if(flag == 2 && status.aktservice->fedev == dvbnode)
442                        {
443                                dvbnode = dvbnode->next;
444                                continue;
445                        }
446                        found = 0;
447                        //check if tuner is loop and looptuner is locked
448                        tmpstr = getconfigbyval(dvbnode->feshortname, NULL);
449                        CharPtrTmp[0] = NULL;
450                        while(tmpstr != NULL) //found loop tuner
451                        {
452                                tmpdvbnode = fegetbyshortname(tmpstr);
453                                if(tmpdvbnode != NULL)
454                                {
455                                        if(tmpdvbnode->feakttransponder != NULL && (tmpdvbnode->feaktpolarization != tpnode->polarization || tmpdvbnode->feakttransponder->orbitalpos != tpnode->orbitalpos) && (tmpdvbnode->felock != 0 || (flag == 2 && tmpdvbnode->felock == 0)))
456                                        {
457                                                found = -1;
458                                                break;
459                                        }
460                                        else
461                                        {
462                                                CharPtrTmp[found] = tmpdvbnode;
463                                                found = found + 1;
464                                        }
465                                }
466                                tmpstr = getconfigbyval(tmpstr, NULL); //loop tuner also loop  ?
467                        }
468                        if(found == -1)
469                        {
470                                dvbnode = dvbnode->next;
471                                continue;
472                        }
473                        CharPtrTmp[found] = NULL;
474                        tmpstr = ostrcat(dvbnode->feshortname, "_sat", 0, 0);
475                        for(i = 1; i <= getmaxsat(dvbnode->feshortname); i++)
476                        {
477                                tmpnr = oitoa(i);
478
479                                orbitalpos = getconfigint(tmpstr, tmpnr);
480                                if(orbitalpos == tpnode->orbitalpos)
481                                {
482                                        fegetconfig(dvbnode, tpnode, &aktnr, tmpnr);
483                                        if(flag == 3)
484                                                band = calclof(dvbnode, tpnode, aktnr, 0);
485                                        else
486                                                band = calclof(dvbnode, tpnode, aktnr, 1);
487                                        found = 0;
488                                        while(CharPtrTmp[found] != NULL)
489                                        {
490                                                if(CharPtrTmp[found]->feakttransponder != NULL)
491                                                {
492                                                        if(CharPtrTmp[found]->feaktband != band && (CharPtrTmp[found]->felock != 0 || (flag == 2 && CharPtrTmp[found]->felock == 0)))
493                                                        {
494                                                                found = 99;
495                                                                break;
496                                                        }
497                                                }
498                                                found = found + 1;
499                                        }
500                                        if(found == 99)
501                                        {
502                                                found = 0;
503                                                free(tmpnr); tmpnr = NULL;
504                                                continue;
505                                        }       
506                                        if(flag == 1)
507                                        {
508                                                free(tmpstr); tmpstr = NULL;
509                                                free(tmpnr); tmpnr = NULL;
510                                                return dvbnode;
511                                        }
512                                        found = 0;
513                                        while(CharPtrTmp[found] != NULL)
514                                        {
515                                                CharPtrTmp[found]->feaktband = band;
516                                                CharPtrTmp[found]->feaktpolarization = tpnode->polarization;
517                                                found = found + 1;
518                                        }
519                                        dvbnode->felasttransponder = dvbnode->feakttransponder;
520                                        dvbnode->feakttransponder = tpnode;
521                                        dvbnode->feaktpolarization = tpnode->polarization;
522                                        free(dvbnode->feaktnr);
523                                        if(aktnr != NULL)
524                                                dvbnode->feaktnr = ostrcat(aktnr, NULL, 0, 0);
525                                        else
526                                                dvbnode->feaktnr = NULL;
527                                        free(tmpstr); tmpstr = NULL;
528                                        free(tmpnr); tmpnr = NULL;
529                                        if(flag != 1) debug(200, "found free tuner witch same orbitalpos %s", dvbnode->feshortname);
530                                        return dvbnode;
531                                }
532                                free(tmpnr); tmpnr = NULL;
533                        }
534                        free(tmpstr); tmpstr = NULL;
535                }
536                dvbnode = dvbnode->next;
537        }
538        if(dvbfirst != NULL)
539                dvbnode = dvbfirst;
540        else
541                dvbnode = dvbdev;
542
543        //suche loop tuner, wo der haupttuner
544        //die gewuenschte orbitalpos kann, nicht belegt ist
545        //und auf der gleichen poarization/band ist, wo wir hintunen wollen
546        while(dvbnode != NULL)
547        {
548                //FRONTENDDEV first in the list
549                if(dvbnode->type != FRONTENDDEV) break;
550
551                //check if tuner is deactivate
552                if(dvbnode->deactive == 1)
553                {
554                        dvbnode = dvbnode->next;
555                        continue;
556                }
557                if(dvbnode->type == FRONTENDDEV && dvbnode->feinfo->type == tpnode->fetype && dvbnode->felock == 0)
558                {
559                        if(flag == 2 && status.aktservice->fedev == dvbnode)
560                        {
561                                dvbnode = dvbnode->next;
562                                continue;
563                        }
564                        if(getconfig(dvbnode->feshortname, NULL) == NULL)
565                        {
566                                dvbnode = dvbnode->next;
567                                continue;                               
568                        }
569                        //check if tuner is loop and an other loopt is locked
570                        found = 0;
571                        tmpstr = getconfigbyval(dvbnode->feshortname, NULL);
572                        while(tmpstr != NULL) //found loop tuner
573                        {
574                                tmpdvbnode = fegetbyshortname(tmpstr);
575                                if(tmpdvbnode != NULL)
576                                {
577                                        if(tmpdvbnode->feakttransponder != NULL && (tmpdvbnode->feaktpolarization != tpnode->polarization || tmpdvbnode->feakttransponder->orbitalpos != tpnode->orbitalpos) && (tmpdvbnode->felock != 0 || (flag == 2 && tmpdvbnode->felock == 0)))
578                                        {
579                                                found = -1;
580                                                break;
581                                        }
582                                        else
583                                        {
584                                                CharPtrTmp[found] = tmpdvbnode;
585                                                found = found + 1;
586                                        }
587                                }
588                                tmpstr = getconfigbyval(tmpstr, NULL); //loop tuner also loop  ?
589                        }
590                        if(found == -1)
591                        {
592                                dvbnode = dvbnode->next;
593                                continue;
594                        }       
595                        //check if tuner is loop an looptuner is locked
596                        tmpstr = getconfig(dvbnode->feshortname, NULL);
597                        while(tmpstr != NULL) //found loop tuner
598                        {
599                                tmpdvbnode = fegetbyshortname(tmpstr);
600                                if(tmpdvbnode != NULL)
601                                {
602                                        if(tmpdvbnode->feakttransponder != NULL && (tmpdvbnode->feaktpolarization != tpnode->polarization || tmpdvbnode->feakttransponder->orbitalpos != tpnode->orbitalpos) && (tmpdvbnode->felock != 0 || (flag == 2 && tmpdvbnode->felock == 0)))
603                                        {
604                                                found = -1;
605                                                break;
606                                        }
607                                        else
608                                        {
609                                                CharPtrTmp[found] = tmpdvbnode;
610                                                found = found + 1;
611                                        }
612                                }
613                                tmpstr = getconfig(tmpstr, NULL);
614                        }
615                        CharPtrTmp[found] = NULL;
616                        if(found == -1)
617                        {
618                                dvbnode = dvbnode->next;
619                                continue;
620                        }
621       
622                        tmpstr = ostrcat(tmpdvbnode->feshortname, "_sat", 0, 0);
623                        for(i = 1; i <= getmaxsat(tmpdvbnode->feshortname); i++)
624                        {
625                                tmpnr = oitoa(i);
626                                orbitalpos = getconfigint(tmpstr, tmpnr);
627                                if(orbitalpos == tpnode->orbitalpos)
628                                {
629                                        fegetconfig(tmpdvbnode, tpnode, &aktnr, tmpnr);
630                                        if(flag == 3)
631                                                band = calclof(dvbnode, tpnode, aktnr, 0);
632                                        else
633                                                band = calclof(dvbnode, tpnode, aktnr, 1);
634                                        found = 0;
635                                        while(CharPtrTmp[found] != NULL)
636                                        {
637                                                if(CharPtrTmp[found]->feaktband != band && (CharPtrTmp[found]->felock != 0 || (flag >= 2 && CharPtrTmp[found]->felock == 0)))   
638                                                {
639                                                        found = 99;
640                                                        break;
641                                                }
642                                        }
643                                        if(found == 99)
644                                        {
645                                                found = 0;
646                                                free(tmpnr); tmpnr = NULL;
647                                                continue;
648                                        }
649                                               
650                                        if(flag == 1)
651                                        {
652                                                free(tmpstr); tmpstr = NULL;
653                                                free(tmpnr); tmpnr = NULL;
654                                                return dvbnode;
655                                        }
656                                        found = 0;
657                                        while(CharPtrTmp[found] != NULL)
658                                        {
659                                                CharPtrTmp[found]->feaktband = band;
660                                                CharPtrTmp[found]->feaktpolarization = tpnode->polarization;
661                                                found = found + 1;
662                                        }
663                                        dvbnode->felasttransponder = dvbnode->feakttransponder;
664                                        dvbnode->feakttransponder = tpnode;
665                                        dvbnode->feaktpolarization = tpnode->polarization;
666                                        free(dvbnode->feaktnr);
667                                        if(aktnr != NULL)
668                                                dvbnode->feaktnr = ostrcat(aktnr, NULL, 0, 0);
669                                        else
670                                                dvbnode->feaktnr = NULL;
671                                        free(tmpstr); tmpstr = NULL;
672                                        free(tmpnr); tmpnr = NULL;
673                                        if(flag != 1) debug(200, "found free looptuner witch same orbitalpos/polarization/band %s main: %s", dvbnode->feshortname, tmpdvbnode->feshortname);
674                                        return dvbnode;
675                                }
676                                free(tmpnr); tmpnr = NULL;
677                        }
678                        free(tmpstr); tmpstr = NULL;
679                }
680                dvbnode = dvbnode->next;
681        }
682
683        return NULL;
684}
685
686int feopen(struct dvbdev* node, char *fedev)
687{
688        int fd = -1;
689
690        if(node != NULL)
691        {       
692                if((fd = open(node->dev, O_RDWR | O_NONBLOCK)) < 0)
693                        debug(200, "open frontend failed %s", node->dev);
694                node->fd = fd;
695        }
696        else
697        {
698                if((fd = open(fedev, O_RDWR | O_NONBLOCK)) < 0)
699                        debug(200, "open frontend failed %s", fedev);
700        }
701
702        closeonexec(fd);
703        return fd;
704}
705
706void feclose(struct dvbdev* node, int fd)
707{
708        if(node != NULL)
709        {
710                close(node->fd);
711                node->fd = -1;
712        }
713        else
714                close(fd);
715}
716
717int fegetunlock(struct dvbdev* node)
718{
719        fe_status_t status;
720
721        if(node == NULL)
722        {
723                err("NULL detect");
724                return 1;
725        }
726
727#ifdef SIMULATE
728        return 0;
729#endif
730
731        if(ioctl(node->fd, FE_READ_STATUS, &status) == -1)
732                perr("FE_READ_STATUS");
733
734        if(status & FE_HAS_LOCK)
735                return 0;
736        else
737                return 1;
738}
739
740int fewait(struct dvbdev* node)
741{
742        //struct dvb_frontend_event ev;
743        fe_status_t status;
744        fe_status_t status_m = 0;
745
746        int count = 0;
747
748        if(node == NULL)
749        {
750                err("NULL detect");
751                return 1;
752        }
753
754#ifdef SIMULATE
755        return 0;
756#endif
757
758        int timer = 500;
759
760#ifdef MIPSEL
761        timer = 2000;
762#endif
763
764#ifdef ARM
765        timer = 300;
766#endif
767
768        //wait for tuner ready
769        debug(200, "wait for tuner start");
770        while(count <= timer)
771        {
772                count++;
773
774                //ioctl(node->fd, FE_GET_EVENT, &ev);
775                //if(ev.status & FE_HAS_LOCK)
776                //      return 0;
777                ioctl(node->fd, FE_READ_STATUS, &status);
778                if(status != 0)
779                {
780                        if(status_m != status)
781                        {
782                                debug(200, "status=%02x, fe_lock=%02x, count=%d", status, FE_HAS_LOCK, count);
783                                status_m = status;
784                        }
785                }
786
787                if(errno == ERANGE)
788                {
789                        usleep(1000);
790                        continue;
791                }
792
793                if(status & FE_HAS_LOCK)
794                {
795        //              if(FE_HAS_SYNC | FE_HAS_LOCK)
796                        debug(200, "wait for tuner end with 0");
797                        return 0;
798                }
799                if(node != NULL && ostrstr(node->feinfo->name, "BCM45208") != NULL)
800                {
801                        if(status & FE_TIMEDOUT)
802                        {
803                                debug(200, "wait for tuner end with FE_TIMEDOUT");
804                                return 1;
805                        }
806                }
807                usleep(1000);
808        }
809        debug(200, "wait for tuner end");
810        //if(ev.status & FE_HAS_LOCK)
811        //      return 0;
812        if(status & FE_HAS_LOCK)
813//      if(FE_HAS_SYNC | FE_HAS_LOCK)
814                return 0;
815        else
816                return 1;
817}
818
819void fegetfrontend(struct dvbdev* node)
820{
821        if(node == NULL)
822        {
823                err("NULL detect");
824                return;
825        }
826
827#if DVB_API_VERSION >= 5
828        struct dtv_property p[8];
829        struct dtv_properties cmdseq;
830        cmdseq.props = p;
831
832        p[0].cmd = DTV_DELIVERY_SYSTEM;
833        p[1].cmd = DTV_FREQUENCY;
834        p[2].cmd = DTV_MODULATION;
835        p[3].cmd = DTV_SYMBOL_RATE;
836        p[4].cmd = DTV_INNER_FEC;
837        p[5].cmd = DTV_INVERSION;
838        p[6].cmd = DTV_ROLLOFF;
839        p[7].cmd = DTV_PILOT;
840        cmdseq.num = 8;
841       
842        if(ioctl(node->fd, FE_GET_PROPERTY, &cmdseq) < 0)
843        {
844                perr("FE_GET_PROPERTY");
845        }
846        else
847        {
848                debug(200, "frontend akt delivery system = %d", p[0].u.data);
849                debug(200, "frontend akt frequency = %d", p[1].u.data);
850                debug(200, "frontend akt inversion = %d", p[5].u.data);
851                debug(200, "frontend akt symbol_rate = %d", p[3].u.data);
852                debug(200, "frontend akt fec_inner = %d", p[4].u.data);
853                debug(200, "frontend akt modulation = %d", p[2].u.data);
854                debug(200, "frontend akt rolloff = %d", p[6].u.data);
855                debug(200, "frontend akt pilot = %d", p[7].u.data);
856        }
857#else
858        struct dvb_frontend_parameters fe_param;
859
860        if(ioctl(node->fd, FE_GET_FRONTEND, &fe_param) < 0)
861        {
862                perr("FE_GET_FRONTEND");
863        }
864        else
865        {
866                debug(200, "frontend akt frequency = %d", fe_param.frequency);
867                debug(200, "frontend akt inversion = %d", fe_param.inversion);
868                debug(200, "frontend akt u.qpsk.symbol_rate = %d", fe_param.u.qpsk.symbol_rate);
869                debug(200, "frontend akt u.qam.symbol_rate = %d", fe_param.u.qam.symbol_rate);
870                debug(200, "frontend akt u.qpsk.fec_inner = %d", fe_param.u.qpsk.fec_inner);
871                debug(200, "frontend akt u.qam.fec_inner = %d", fe_param.u.qam.fec_inner);
872                debug(200, "frontend akt u.qam.modulation = %d", fe_param.u.qam.modulation);
873        }
874#endif
875}
876
877int fesettone(struct dvbdev* node, fe_sec_tone_mode_t tone, int wait)
878{
879        int ret = 0;
880       
881        if(node == NULL)
882        {
883                err("NULL detect");
884                return 1;
885        }
886
887        debug(200, "FE_SET_TONE: %d (%s)", tone, node->feshortname);
888        if(ioctl(node->fd, FE_SET_TONE, tone) == -1)
889        {
890                perr("FE_SET_TONE");
891                ret = 1;
892        }
893        else
894        {
895                node->feakttone = tone;
896                usleep(wait * 1000);
897        }
898       
899        return ret;
900}
901
902//flag 0: reset tuner params on volt off
903//flag 1: don't reset tuner params on volt off
904int fesetvoltage(struct dvbdev* node, fe_sec_voltage_t volt, int wait)
905{
906        int ret = 0;
907       
908        if(node == NULL)
909        {
910                err("NULL detect");
911                return 1;
912        }
913
914        debug(200, "FE_SET_VOLT: %d (%s)", volt, node->feshortname);
915        if(ioctl(node->fd, FE_SET_VOLTAGE, volt) == -1)
916        {
917                perr("FE_SET_VOLTAGE");
918                ret = 1;
919        }
920        else
921        {
922                node->feaktvolt = volt;
923                if(wait > 0) usleep(wait * 1000);
924
925                if(volt == SEC_VOLTAGE_OFF)
926                {
927                        node->feakttransponder = NULL;
928                        node->felasttransponder = NULL;
929                        node->feunicable = 0;
930                        node->feloffrequency = 0;
931                        node->feaktband = 0;
932                        node->feaktpolarization = 0;
933                        node->feakttone = 0;
934                }
935        }
936
937        return ret;
938}
939
940void fediseqcsendburst(struct dvbdev* node, fe_sec_mini_cmd_t burst, int wait)
941{
942        if(node == NULL)
943        {
944                err("NULL detect");
945                return;
946        }
947
948        debug(200, "FE_DISEQC_SEND_BURST: %d (%s)", burst, node->feshortname);
949        if(ioctl(node->fd, FE_DISEQC_SEND_BURST, burst) == -1)
950                perr("FE_DISEQC_SEND_BURST");
951        usleep(wait * 1000);
952}
953
954void fediseqcsendmastercmd(struct dvbdev* node, struct dvb_diseqc_master_cmd *cmd, int wait)
955{
956        int i, repeat = 0, imsg = 0;
957        char* tmpstr = NULL;
958
959        if(node == NULL)
960        {
961                err("NULL detect");
962                return;
963        }
964       
965        if(cmd == NULL) return;
966        if(cmd->msg_len == 0) return;
967
968        tmpstr = ostrcat(node->feshortname, "_diseqc_repeat", 0, 0);
969        repeat = getconfigint(tmpstr, node->feaktnr);
970        free(tmpstr); tmpstr = NULL;
971        if(repeat < 1) repeat = 1;
972
973        for(i = 0; i < repeat; i++)
974        {
975                if(ioctl(node->fd, FE_DISEQC_SEND_MASTER_CMD, cmd) == -1)
976                {
977                        perr("FE_DISEQC_SEND_MASTER_CMD");
978                }
979                usleep(wait * 1000);
980        }
981        imsg = (cmd->msg[0] << 24) | (cmd->msg[1] << 16) | (cmd->msg[2] << 8) | cmd->msg[3];
982        debug(200, "DISEQC Master cmd (%s -> %04X)", node->feshortname, imsg);
983}
984
985void fesdiseqcpoweron(struct dvbdev* node)
986{
987        struct dvb_diseqc_master_cmd cmd = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0};
988
989        if(node == NULL)
990        {
991                err("NULL detect");
992                return;
993        }
994
995        cmd.msg[0] = 0xE0;
996        cmd.msg[1] = 0x00;
997        cmd.msg[2] = 0x03;
998        cmd.msg_len = 3;
999
1000        debug(200, "DISEQC Power on (%s)", node->feshortname);
1001        fediseqcsendmastercmd(node, &cmd, 100);
1002}
1003
1004void fesdiseqcreset(struct dvbdev* node)
1005{
1006        struct dvb_diseqc_master_cmd cmd = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0};
1007       
1008        if(node == NULL)
1009        {
1010                err("NULL detect");
1011                return;
1012        }
1013
1014        cmd.msg[0] = 0xE0;
1015        cmd.msg[1] = 0x00;
1016        cmd.msg[2] = 0x00;
1017        cmd.msg_len = 3;
1018
1019        debug(200, "DISEQC Reset (%s)", node->feshortname);
1020        fediseqcsendmastercmd(node, &cmd, 100);
1021}
1022
1023void fesdiseqcstandby(struct dvbdev* node)
1024{
1025        struct dvb_diseqc_master_cmd cmd = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0};
1026       
1027        if(node == NULL)
1028        {
1029                err("NULL detect");
1030                return;
1031        }
1032       
1033        cmd.msg[0] = 0xE0;
1034        cmd.msg[1] = 0x00;
1035        cmd.msg[2] = 0x02;
1036        cmd.msg_len = 3;
1037
1038        debug(200, "DISEQC Standby (%s)", node->feshortname);
1039        fediseqcsendmastercmd(node, &cmd, 100);
1040}
1041
1042void fediseqcrotor(struct dvbdev* node, struct transponder* tpnode, int pos, int flag)
1043{
1044        int orbitalpos = 0;
1045        fe_sec_voltage_t oldvolt = 0;
1046        fe_sec_tone_mode_t oldtone = 0;
1047        struct dvb_diseqc_master_cmd cmd = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0};
1048       
1049        if(node == NULL)
1050        {
1051                err("NULL detect");
1052                return;
1053        }
1054       
1055        fesdiseqcpoweron(node);
1056       
1057        oldvolt = node->feaktvolt;
1058        oldtone = node->feakttone;
1059
1060        if(tpnode == NULL)
1061                orbitalpos = 0;
1062        else
1063                orbitalpos = tpnode->orbitalpos;
1064       
1065        //float speed13V = 1.5; //1.5 Grad pro sec
1066        float speed18V = 1; //2.4 Grad pro sek
1067        float degreesmov, waittime;
1068       
1069        switch(flag)
1070        {
1071                case 0: //stop move
1072                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x60; cmd.msg_len = 3;
1073                        debug(200, "DISEQC Rotorpos stop move (%s)", node->feshortname);
1074                        break;
1075                case 1: //disable limits
1076                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x63; cmd.msg_len = 3;
1077                        debug(200, "DISEQC Rotorpos disable limits (%s)", node->feshortname);
1078                        break;
1079                case 2: //enable limits
1080                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x6A; cmd.msg[3] = 0x00; cmd.msg_len = 4;
1081                        debug(200, "DISEQC Rotorpos enable limits (%s)", node->feshortname);
1082                        break;
1083                case 3: //set east limit
1084                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x66; cmd.msg_len = 3;
1085                        debug(200, "DISEQC Rotorpos set east limit (%s)", node->feshortname);
1086                        break;
1087                case 4: //set west limit
1088                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x67; cmd.msg_len = 3;
1089                        debug(200, "DISEQC Rotorpos set west limit (%s)", node->feshortname);
1090                        break;
1091                case 5: //move east cont.
1092                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x68; cmd.msg[3] = 0x00; cmd.msg_len = 4;
1093                        debug(200, "DISEQC Rotorpos move east cont. (%s)", node->feshortname);
1094                        break;
1095                case 6: //move west cont.
1096                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x69; cmd.msg[3] = 0x00; cmd.msg_len = 4;
1097                        debug(200, "DISEQC Rotorpos move west cont. (%s)", node->feshortname);
1098                        break;
1099                case 7: //store pos
1100                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x6A; cmd.msg[3] = pos; cmd.msg_len = 4;
1101                        debug(200, "DISEQC Rotorpos store pos=%d (%s)", pos, node->feshortname);
1102                        break;
1103                case 8: //goto pos
1104                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x6B; cmd.msg[3] = pos; cmd.msg_len = 4;
1105                        debug(200, "DISEQC Rotorpos goto pos=%d (%s)", pos, node->feshortname);
1106                        break;
1107                case 9: //step xx pos east
1108                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x68; cmd.msg[3] = 256 - pos; cmd.msg_len = 4;
1109                        debug(200, "DISEQC Rotorpos step east pos=%d (%s)", pos, node->feshortname);
1110                        break;
1111                case 10: //step xx pos west
1112                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x69; cmd.msg[3] = 256 - pos; cmd.msg_len = 4;
1113                        debug(200, "DISEQC Rotorpos step west pos=%d (%s)", pos, node->feshortname);
1114                        break;
1115                case 11: //goto xx
1116                        cmd.msg[0] = 0xE0; cmd.msg[1] = 0x31; cmd.msg[2] = 0x6E; cmd.msg[3] = (pos >> 8) & 0xff; cmd.msg[4] = pos & 0xff; cmd.msg_len = 5;
1117                        debug(200, "DISEQC Rotorpos goto xx pos=%d (%s)", pos, node->feshortname);
1118                        break;
1119        }
1120
1121        if(flag >= 0 && flag < 7)
1122        {
1123                fesetvoltage(node, SEC_VOLTAGE_18, 15);
1124                fesettone(node, SEC_TONE_OFF, 15);
1125                fediseqcsendmastercmd(node, &cmd, 100);
1126        }
1127
1128        if((flag == 7 || flag == 9 || flag == 10) && pos != 0)
1129        {
1130                fesetvoltage(node, SEC_VOLTAGE_18, 15);
1131                fesettone(node, SEC_TONE_OFF, 15);
1132                fediseqcsendmastercmd(node, &cmd, 100);
1133        }
1134
1135        if((flag == 8 || flag == 11) && (orbitalpos == 0 || status.rotoroldorbitalpos == 0 || orbitalpos != status.rotoroldorbitalpos))
1136        {
1137                fesetvoltage(node, SEC_VOLTAGE_18, 15);
1138                fesettone(node, SEC_TONE_OFF, 15);
1139                fediseqcsendmastercmd(node, &cmd, 100);
1140
1141                if(status.rotoroldorbitalpos == 0 || orbitalpos == 0)
1142                        waittime = 15;
1143                else
1144                {
1145                        degreesmov = abs(orbitalpos - status.rotoroldorbitalpos) / 10;
1146                        waittime = (int)ceil((float)degreesmov / (float)speed18V);
1147                }
1148
1149                status.rotoroldorbitalpos = orbitalpos;
1150                sleep(waittime);
1151        }
1152       
1153        fesetvoltage(node, oldvolt, 15);
1154        fesettone(node, oldtone, 15);
1155}
1156
1157void fesetunicable(struct dvbdev* node)
1158{
1159        int unicabletune = 0;
1160        char* tmpstr = NULL;
1161        struct dvb_diseqc_master_cmd cmd = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0};
1162
1163        if(node == NULL)
1164        {
1165                err("NULL detect");
1166                return;
1167        }
1168
1169        tmpstr = ostrcat(node->feshortname, "_lnb_satcr", 0, 0);
1170        int satcr = getconfigint(tmpstr, node->feaktnr) - 1;
1171        if(satcr < 0) satcr = 0;
1172        free(tmpstr); tmpstr = NULL;
1173
1174        tmpstr = ostrcat(node->feshortname, "_diseqc", 0, 0);
1175        int aktdiseqc = getconfigint(tmpstr, node->feaktnr);
1176        if(aktdiseqc < 1) aktdiseqc = 1;
1177        free(tmpstr); tmpstr = NULL;
1178
1179        unicabletune |= ((satcr & 0x7) << 13);
1180        unicabletune |= (((aktdiseqc - 1) & 0x1) << 12);
1181        unicabletune |= (((!node->feaktpolarization) & 0x1) << 11);
1182        unicabletune |= ((node->feaktband & 0x1) << 10);
1183        unicabletune |= ((node->feloffrequency / 1000) & 0x3ff);
1184
1185        debug(200, "unicabletune %04X", unicabletune);
1186       
1187        if(status.firstunicablewait == 0)
1188        {
1189                status.firstunicablewait = getconfigint("firstunicablewait", NULL);
1190                if(status.firstunicablewait == 0)
1191                        status.firstunicablewait = 1000;
1192        }               
1193       
1194        if(status.firstunicablewait > 0)
1195        {
1196                usleep(status.firstunicablewait * 1000);
1197                status.firstunicablewait = -1;
1198        }
1199       
1200        fesetvoltage(node, SEC_VOLTAGE_13, 15);
1201        fesetvoltage(node, SEC_VOLTAGE_18, 15);
1202        fesettone(node, SEC_TONE_OFF, 15);
1203
1204        //feunicable
1205        //byte1 (bit 7/6/5) -> satcr number
1206        //byte1 (bit 4/3/2) -> lnb number
1207        //byte1 (bit 1/0) -> frequ
1208        //byte0 -> frequ
1209       
1210        cmd.msg[0] = 0xE0;
1211        cmd.msg[1] = 0x10;
1212        cmd.msg[2] = 0x5A;
1213        cmd.msg[3] = (unicabletune >> 8) & 0xff;
1214        cmd.msg[4] = unicabletune & 0xff;
1215        cmd.msg_len = 5;
1216
1217        debug(200, "send diseqc unicable cmd (%s)", node->feshortname);
1218        fediseqcsendmastercmd(node, &cmd, 100);
1219        fesetvoltage(node, SEC_VOLTAGE_13, 15);
1220}
1221
1222void fediseqcset(struct dvbdev* node, struct transponder* tpnode)
1223{
1224        char* tmpstr = NULL;
1225        int toneburst = 0, cmdorder = 0, input = 0, uinput = 0, diseqmode = 0, rotorpos = 0, latpos = 0, longpos = 0;
1226        float latitude = 0, longitude = 0;
1227        fe_sec_mini_cmd_t mini = -1;
1228        struct dvb_diseqc_master_cmd cmd = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0};
1229        struct dvb_diseqc_master_cmd ucmd = {{0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 0};
1230       
1231        if(node == NULL) return;
1232       
1233        tmpstr = ostrcat(node->feshortname, "_diseqc_committedcmd", 0, 0);
1234        input = getconfigint(tmpstr, node->feaktnr);
1235        free(tmpstr); tmpstr = NULL;
1236        tmpstr = ostrcat(node->feshortname, "_diseqc_uncommittedcmd", 0, 0);
1237        uinput = getconfigint(tmpstr, node->feaktnr);
1238        free(tmpstr); tmpstr = NULL;
1239        tmpstr = ostrcat(node->feshortname, "_diseqc_mode", 0, 0);
1240        diseqmode = getconfigint(tmpstr, node->feaktnr);
1241        free(tmpstr); tmpstr = NULL;
1242        tmpstr = ostrcat(node->feshortname, "_diseqc_cmdorder", 0, 0);
1243        cmdorder = getconfigint(tmpstr, node->feaktnr);
1244        free(tmpstr); tmpstr = NULL;
1245        tmpstr = ostrcat(node->feshortname, "_diseqc_toneburst", 0, 0);
1246        toneburst = getconfigint(tmpstr, node->feaktnr);
1247        free(tmpstr); tmpstr = NULL;
1248        tmpstr = ostrcat(node->feshortname, "_diseqc_rotorpos", 0, 0);
1249        rotorpos = getconfigint(tmpstr, node->feaktnr);
1250        free(tmpstr); tmpstr = NULL;
1251       
1252        latitude = getconfigfloat("latitude", NULL);
1253        longitude = getconfigfloat("longitude", NULL);
1254        latpos = getconfigint("latpos", NULL);
1255        longpos = getconfigint("longpos", NULL);
1256
1257        tmpstr = ostrcat(node->feshortname, "_diseqc", 0, 0);
1258        int aktdiseqc = getconfigint(tmpstr, node->feaktnr);
1259        if(aktdiseqc < 1) aktdiseqc = 1;
1260        free(tmpstr); tmpstr = NULL;
1261
1262        debug(200, "set diseqc: number=%d, band=%d, pol=%d, diseqmode=%d, input=%d, uinput=%d, cmdorder=%d, toneburst=%d (%s)", aktdiseqc, node->feaktband, node->feaktpolarization, diseqmode, input, uinput, cmdorder, toneburst, node->feshortname);
1263         
1264        switch(toneburst)
1265        {
1266                case 1: mini = SEC_MINI_A; break;
1267                case 2: mini = SEC_MINI_B; break;
1268        }
1269       
1270        if(diseqmode == 100) // Tonburst A/B
1271        {
1272                debug(200, "set diseqc: Tonburst A/B (%s)", node->feshortname);
1273                if(mini == -1)
1274                        mini = (aktdiseqc - 1) % 2 ? SEC_MINI_B : SEC_MINI_A;
1275                fediseqcsendburst(node, mini, 15);
1276                return;
1277        }
1278               
1279        if(diseqmode == 0 || diseqmode == 1) // Diseqc 1.0 + 1.1
1280        {
1281                debug(200, "set committed switch (%s)", node->feshortname);
1282                fesdiseqcpoweron(node);
1283                cmd.msg[0] = 0xE0;
1284                cmd.msg[1] = 0x10;
1285                cmd.msg[2] = 0x38;
1286
1287                if(input == 0)
1288                        cmd.msg[3] = 0xF0 | ((((aktdiseqc - 1) * 4) & 0x0F) | (node->feaktband ? 1 : 0) | (node->feaktpolarization ? 0 : 2));
1289                else
1290                        cmd.msg[3] = 0xF0 + ((input - 1) & 0x0F);
1291
1292                cmd.msg_len = 4;
1293        }
1294
1295        if(diseqmode == 1) // Diseqc 1.1
1296        {
1297                if(uinput > 0)
1298                {
1299                        debug(200, "set uncommitted switch (%s)", node->feshortname);
1300                        fesdiseqcpoweron(node);
1301                        ucmd.msg[0] = 0xE0;
1302                        ucmd.msg[1] = 0x10;
1303                        ucmd.msg[2] = 0x39;
1304                        ucmd.msg[3] = 0xF0 + ((uinput - 1) & 0x0F);
1305                        ucmd.msg_len = 4;
1306                }
1307        }
1308                 
1309        switch(cmdorder)
1310        {
1311                case 1:
1312                        if(mini != -1) fediseqcsendburst(node, mini, 15);
1313                        fediseqcsendmastercmd(node, &cmd, 100);
1314                        break;
1315                case 2:
1316                        fediseqcsendmastercmd(node, &cmd, 100);
1317                        if(uinput > 0) fediseqcsendmastercmd(node, &ucmd, 100);
1318                        if(mini != -1) fediseqcsendburst(node, mini, 15);
1319                        break;
1320                case 3:
1321                        if(mini != -1) fediseqcsendburst(node, mini, 15);
1322                        fediseqcsendmastercmd(node, &cmd, 100);
1323                        if(uinput > 0) fediseqcsendmastercmd(node, &ucmd, 100);
1324                        break;
1325                case 4:
1326                        if(uinput > 0) fediseqcsendmastercmd(node, &ucmd, 100);
1327                        fediseqcsendmastercmd(node, &cmd, 100);
1328                        if(mini != -1) fediseqcsendburst(node, mini, 15);
1329                        break;
1330                case 5:
1331                        if(mini != -1) fediseqcsendburst(node, mini, 15);
1332                        if(uinput > 0) fediseqcsendmastercmd(node, &ucmd, 100);
1333                        fediseqcsendmastercmd(node, &cmd, 100);
1334                        break;
1335                default:
1336                        fediseqcsendmastercmd(node, &cmd, 100);
1337                        if(mini != -1) fediseqcsendburst(node, mini, 15);
1338                        break;
1339        }
1340       
1341        if(diseqmode == 2) // Diseqc 1.2
1342        {
1343                fediseqcrotor(node, tpnode, rotorpos, 8);
1344        }
1345       
1346        if(diseqmode == 3) // Diseqc 1.3 (USALS)
1347        {
1348                double orbitalpos = tpnode->orbitalpos / 10.00;
1349
1350                if(latpos == 1) // south
1351                        latitude = -latitude;
1352
1353                if(longpos == 1) // west
1354                        longitude = 360 - longitude;
1355
1356                double satHourAngle = calcSatHourangle(orbitalpos, latitude, longitude);
1357                int gotoXTable[10] = {0x00, 0x02, 0x03, 0x05, 0x06, 0x08, 0x0A, 0x0B, 0x0D, 0x0E};
1358
1359                if(latitude >= 0) // Northern Hemisphere
1360                {
1361                        int tmp = (int)round(fabs(180 - satHourAngle) * 10.0);
1362                        rotorpos = (tmp / 10) * 0x10 + gotoXTable[tmp % 10];
1363
1364                        if(satHourAngle < 180) // the east
1365                                rotorpos |= 0xE000;
1366                        else // west
1367                                rotorpos |= 0xD000;
1368                }
1369                else // Southern Hemisphere
1370                {
1371                        if(satHourAngle < 180) // the east
1372                        {
1373                                int tmp = (int)round(fabs(satHourAngle) * 10.0);
1374                                rotorpos = (tmp / 10) * 0x10 + gotoXTable[tmp % 10];
1375                                rotorpos |= 0xD000;
1376                        }
1377                        else // west
1378                        {
1379                                int tmp = (int)round(fabs(360 - satHourAngle) * 10.0);
1380                                rotorpos = (tmp / 10) * 0x10 + gotoXTable[tmp % 10];
1381                                rotorpos |= 0xE000;
1382                        }
1383                }
1384                debug(200, "orbitalpos=%f, latitude=%f, longitude=%f, rotorpos=%04x", orbitalpos, latitude, longitude, rotorpos);
1385
1386                fediseqcrotor(node, tpnode, rotorpos, 11);
1387        }
1388}
1389
1390void feset(struct dvbdev* node, struct transponder* tpnode)
1391{
1392        int voltagemode = 0, tonemode = 0;
1393        fe_sec_tone_mode_t tone;
1394        fe_sec_voltage_t volt;
1395        struct dvbdev* dvbnode = dvbdev;
1396        char* tmpstr = NULL;
1397
1398        if(node == NULL)
1399        {
1400                err("NULL detect");
1401                return;
1402        }
1403
1404        // set volage off from other unused frontend
1405        while(dvbnode != NULL)
1406        {
1407                if(dvbnode->type != FRONTENDDEV) break;
1408                if(dvbnode->type == FRONTENDDEV && dvbnode != node && dvbnode->felock == 0 && dvbnode != status.aktservice->fedev)
1409                {
1410                        fesetvoltage(dvbnode, SEC_VOLTAGE_OFF, 0);
1411                }
1412                dvbnode = dvbnode->next;
1413        }
1414
1415        calclof(node, tpnode, NULL, 0);
1416
1417        tmpstr = ostrcat(node->feshortname, "lnb_voltagemode", 0, 0);
1418        voltagemode = getconfigint(tmpstr, node->feaktnr);
1419        free(tmpstr); tmpstr = NULL;
1420        switch(voltagemode)
1421        {
1422                case 1: volt = SEC_VOLTAGE_13; break;
1423                case 2: volt = SEC_VOLTAGE_18; break;
1424                default: volt = node->feaktpolarization ? SEC_VOLTAGE_13 : SEC_VOLTAGE_18;
1425                         if(node->feunicable == 1) volt = SEC_VOLTAGE_13;
1426        }
1427        fesetvoltage(node, volt, 15);
1428
1429        tmpstr = ostrcat(node->feshortname, "_diseqc", 0, 0);
1430        if(getconfigint(tmpstr, node->feaktnr) == 0 || node->feunicable == 1)
1431        {
1432                debug(200, "don't use diseqc");
1433        }
1434        else
1435        {
1436                fesettone(node, SEC_TONE_OFF, 15);
1437                fediseqcset(node, tpnode);
1438        }
1439        free(tmpstr); tmpstr = NULL;
1440
1441        tmpstr = ostrcat(node->feshortname, "_lnb_tonemode", 0, 0);
1442        tonemode = getconfigint(tmpstr, node->feaktnr);
1443        free(tmpstr); tmpstr = NULL;
1444        switch(tonemode)
1445        {
1446                case 1: tone = SEC_TONE_ON; break;
1447                case 2: tone = SEC_TONE_OFF; break;
1448                default: tone = node->feaktband ? SEC_TONE_ON : SEC_TONE_OFF;
1449                         if(node->feunicable == 1) tone = SEC_TONE_OFF;
1450        }
1451        fesettone(node, tone, 15);
1452}
1453
1454void fediscard(struct dvbdev* node)
1455{
1456        struct dvb_frontend_event ev;
1457        int count = 0;
1458
1459        if(node == NULL)
1460        {
1461                err("NULL detect");
1462                return;
1463        }
1464
1465        /* discard stale QPSK events */
1466        while(count < 20)
1467        {
1468                count++;
1469                if(ioctl(node->fd, FE_GET_EVENT, &ev) == -1)
1470                        break;
1471        }
1472}
1473
1474uint16_t fereadsnr(struct dvbdev* node)
1475{
1476        uint16_t snr = 0;
1477        if(node == NULL)
1478        {
1479                err("NULL detect");
1480                return 0;
1481        }
1482        int signalquality = 0;
1483        int signalqualitydb = 0;
1484//#ifdef ARM
1485#ifdef MIPSEL
1486//#if DVB_API_VERSION >= 5
1487#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 10
1488
1489        int test1 = 0;
1490        int test2 = 0;
1491        struct dtv_property prop[1];
1492        prop[0].cmd = DTV_STAT_CNR;
1493        struct dtv_properties props;
1494        props.props = prop;
1495        props.num = 1;
1496       
1497        if(ioctl(node->fd, FE_GET_PROPERTY,  &props) < 0 && errno != ERANGE)
1498        {
1499                perr("FE_GET_PROPERTY");
1500        }
1501        else
1502        {
1503                for(unsigned int i=0; i<prop[0].u.st.len; i++)
1504                {
1505                        if (prop[0].u.st.stat[i].scale == FE_SCALE_DECIBEL && test1 == 0)
1506                        {
1507                                test1 = 1;
1508                                signalqualitydb = prop[0].u.st.stat[i].svalue / 10;
1509                                printf("***** new snr signalqualitydb:%d\n", signalqualitydb);
1510                        }
1511                        else if (prop[0].u.st.stat[i].scale == FE_SCALE_RELATIVE && test2 == 0)
1512                        {
1513                                test2 = 1;
1514                                signalquality = prop[0].u.st.stat[i].svalue;
1515                                printf("***** new snr signalquality:%d\n", signalquality);
1516                        }
1517                }
1518        }
1519#endif
1520        if(!signalquality && !signalqualitydb)
1521        {
1522                int ret = 0x12345678;
1523                int sat_max = 1600; // we assume a max of 16db here
1524                int ter_max = 2900; // we assume a max of 29db here
1525                int cab_max = 4200; // we assume a max of 42db here
1526                //int atsc_max = 4200; // we assume a max of 42db here
1527               
1528                ioctl(node->fd, FE_READ_SNR, &snr);
1529               
1530                printf("***** old snr signalquality\n");               
1531               
1532                if(ostrstr(node->feinfo->name, "Si2166B") != NULL)
1533                {
1534                        ret = (snr * 240) >> 8;
1535                }
1536                else if (ostrstr(node->feinfo->name, "ATBM781x") != NULL)
1537                {
1538                        ret = snr*10;
1539                }
1540                else if(ostrstr(node->feinfo->name, "BCM4506") != NULL || ostrstr(node->feinfo->name, "BCM4506 (internal)") != NULL || ostrstr(node->feinfo->name, "BCM4505") != NULL || ostrstr(node->feinfo->name, "BCM73625 (G3)") != NULL || ostrstr(node->feinfo->name, "BCM45208") != NULL)
1541                {
1542                        ret = (snr * 100) >> 8;
1543                }
1544                else if (ostrstr(node->feinfo->name, "Si216") != NULL) // all new Models with SI Tuners
1545                {
1546                        ret = snr;
1547                }
1548                signalqualitydb = ret;
1549                if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
1550                {
1551                        signalquality = snr;
1552                }
1553                else
1554                {
1555                        if(node->feinfo->type == FE_QPSK)
1556                                signalquality = (ret >= sat_max ? 65536 : ret * 65536 / sat_max);
1557                        else if(node->feinfo->type == FE_QAM)
1558                                signalquality = (ret >= cab_max ? 65536 : ret * 65536 / cab_max);
1559                        else if(node->feinfo->type == FE_OFDM)
1560                                signalquality = (ret >= ter_max ? 65536 : ret * 65536 / ter_max);
1561                }
1562        }
1563        debug(200, "frontend snr = %02x", signalquality );
1564        return signalquality;
1565#else
1566        ioctl(node->fd, FE_READ_SNR, &snr);
1567        debug(200, "frontend snr = %02x", (snr * 100) / 0xffff);
1568        return snr;
1569#endif
1570}
1571
1572uint16_t fereadsignalstrength(struct dvbdev* node)
1573{
1574        uint16_t signal = 0;
1575
1576        if(node == NULL)
1577        {
1578                err("NULL detect");
1579                return 0;
1580        }
1581//#ifdef ARM
1582//#ifdef MIPSEL
1583#if DVB_API_VERSION > 5 || DVB_API_VERSION == 5 && DVB_API_VERSION_MINOR >= 10
1584        struct dtv_property prop[1];
1585        prop[0].cmd = DTV_STAT_SIGNAL_STRENGTH;
1586        struct dtv_properties props;
1587        props.props = prop;
1588        props.num = 1;
1589        if (ioctl(node->fd, FE_GET_PROPERTY, &props) < 0 && errno != ERANGE)
1590        {
1591                debug(200, "DTV_STAT_SIGNAL_STRENGTH failed");
1592        }
1593        else
1594        {
1595                for(unsigned int i=0; i<prop[0].u.st.len; i++)
1596                {
1597                        if (prop[0].u.st.stat[i].scale == FE_SCALE_RELATIVE)
1598                                signal = prop[0].u.st.stat[i].uvalue;
1599                }
1600        }
1601        if (signal)
1602                return signal;
1603        // fallback to old DVB API
1604//#endif
1605#endif 
1606        if(ioctl(node->fd, FE_READ_SIGNAL_STRENGTH, &signal) < 0 && errno != ERANGE)
1607        {
1608                debug(200, "FE_READ_SIGNAL_STRENGTH failed");
1609        }
1610        else
1611        {
1612                if(ostrstr(node->feinfo->name, "Si2166B") != NULL || ostrstr(node->feinfo->name, "BCM45208") != NULL)
1613                        signal = signal * 1000;
1614                debug(200, "frontend signal = %02x", (signal * 100) / 0xffff);
1615        }
1616        return signal;
1617}
1618
1619uint32_t fereadber(struct dvbdev* node)
1620{
1621        uint32_t ber = 0;
1622
1623        if(node == NULL)
1624        {
1625                err("NULL detect");
1626                return 0;
1627        }
1628
1629        ioctl(node->fd, FE_READ_BER, &ber);
1630        debug(200, "frontend ber = %02x", ber);
1631        return ber;
1632}
1633
1634uint32_t fereaduncorrectedblocks(struct dvbdev* node)
1635{
1636        uint32_t unc = 0;
1637
1638        if(node == NULL)
1639        {
1640                err("NULL detect");
1641                return 0;
1642        }
1643
1644        ioctl(node->fd, FE_READ_UNCORRECTED_BLOCKS, &unc);
1645        debug(200, "frontend unc = %02x", unc);
1646        return unc;
1647}
1648
1649fe_status_t fereadstatus(struct dvbdev* node)
1650{
1651        fe_status_t status;
1652
1653        if(node == NULL)
1654        {
1655                err("NULL detect");
1656                return -1;
1657        }
1658
1659        if(ioctl(node->fd, FE_READ_STATUS, &status) == -1)
1660                perr("FE_READ_STATUS");
1661
1662        debug(200, "frontend status = %02x", status);
1663        if(status & FE_HAS_LOCK) debug(200, "frontend = FE_HAS_LOCK");
1664        if(status & FE_HAS_SIGNAL) debug(200, "frontend = FE_HAS_SIGNAL");
1665        if(status & FE_HAS_CARRIER) debug(200, "frontend = FE_HAS_CARRIER");
1666        if(status & FE_HAS_VITERBI) debug(200, "frontend = FE_HAS_VITERBI");
1667        if(status & FE_HAS_SYNC) debug(200, "frontend = FE_HAS_SYNC");
1668        if(status & FE_TIMEDOUT) debug(200, "frontend = FE_TIMEDOUT");
1669        if(status & FE_REINIT) debug(200, "frontend = FE_REINIT");
1670
1671        return status;
1672}
1673
1674int fetunedvbs(struct dvbdev* node, struct transponder* tpnode)
1675{
1676        if(node == NULL || tpnode == NULL)
1677        {
1678                err("NULL detect");
1679                return 1;
1680        }
1681       
1682        if(node->feunicable == 1)
1683        {
1684                fesetunicable(node);
1685                char* tmpstr = ostrcat(node->feshortname, "_lnb_satcrfrequ", 0, 0);
1686                node->feloffrequency = getconfigint(tmpstr, node->feaktnr) * 1000;
1687                free(tmpstr); tmpstr = NULL;
1688        }
1689
1690#if DVB_API_VERSION >= 5
1691        struct dtv_property p[10];
1692        struct dtv_properties cmdseq;
1693        cmdseq.props = p;
1694
1695        //convert transponderlist for dvbapi5
1696        int system = tpnode->system;
1697        switch(system)
1698        {
1699                case 0: system = SYS_DVBS; break;
1700                case 1: system = SYS_DVBS2; break;
1701                default: system = SYS_DVBS; break;
1702        }
1703
1704        int fec = tpnode->fec;
1705        switch(fec)
1706        {
1707                case 0: fec = FEC_AUTO; break;
1708                case 1: fec = FEC_1_2; break;
1709                case 2: fec = FEC_2_3; break;
1710                case 3: fec = FEC_3_4; break;
1711                case 4: fec = FEC_5_6; break;
1712                case 5: fec = FEC_7_8; break;
1713                case 6: fec = FEC_8_9; break;
1714                case 7: fec = FEC_3_5; break;
1715                case 8: fec = FEC_4_5; break;
1716                case 9: fec = FEC_9_10; break;
1717                case 15: fec = FEC_NONE; break;
1718                default: fec = FEC_AUTO; break;
1719        }
1720        int pilot = tpnode->pilot;
1721        switch(pilot)
1722        {
1723                case 0: pilot = PILOT_OFF; break;
1724                case 1: pilot = PILOT_ON; break;
1725                case 2: pilot = PILOT_AUTO; break;
1726                default: pilot = PILOT_AUTO; break;
1727        }
1728        int rolloff = tpnode->rolloff;
1729        switch(rolloff)
1730        {
1731                case 0: rolloff = ROLLOFF_35; break;
1732                case 1: rolloff = ROLLOFF_25; break;
1733                case 2: rolloff = ROLLOFF_20; break;
1734                default: rolloff = ROLLOFF_35; break;
1735        }
1736
1737        int modulation = tpnode->modulation;
1738        switch(modulation)
1739        {
1740                case 0: modulation = QPSK; break;
1741                case 1: modulation = QPSK; break;
1742                case 2: modulation = PSK_8; break;
1743                case 3: modulation = QAM_16; break;
1744                default: modulation = QPSK; break;
1745        }
1746
1747        p[0].cmd = DTV_CLEAR;
1748        p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
1749        p[2].cmd = DTV_FREQUENCY,       p[2].u.data = node->feloffrequency;
1750        p[3].cmd = DTV_MODULATION,      p[3].u.data = modulation;
1751        p[4].cmd = DTV_SYMBOL_RATE,     p[4].u.data = tpnode->symbolrate;
1752        p[5].cmd = DTV_INNER_FEC,       p[5].u.data = fec;
1753        p[6].cmd = DTV_INVERSION,       p[6].u.data = (fe_spectral_inversion_t) tpnode->inversion;
1754        if(system == SYS_DVBS2)
1755        {
1756                p[7].cmd = DTV_ROLLOFF,         p[7].u.data = rolloff;
1757                p[8].cmd = DTV_PILOT,           p[8].u.data = pilot;
1758                p[9].cmd = DTV_TUNE;
1759                cmdseq.num = 10;
1760        }
1761        else
1762        {
1763                p[7].cmd = DTV_TUNE;
1764                cmdseq.num = 8;
1765        }
1766
1767        debug(200, "new dvbapi: frequ=%d, inversion=%d, pilot=%d, rolloff=%d, fec=%d, sr=%d, modulation=%d, system=%d (%s)", node->feloffrequency, tpnode->inversion, pilot, rolloff, fec, tpnode->symbolrate, modulation, system, node->feshortname);
1768#else
1769        struct dvb_frontend_parameters tuneto;
1770        fe_spectral_inversion_t inversion = tpnode->inversion;
1771
1772        //convert transponderlist for dvbapi3
1773        int fec = tpnode->fec;
1774        if(tpnode->system == 1)
1775        {
1776                if(tpnode->modulation == 1) fec = fec + 9;
1777                if(tpnode->modulation == 2) fec = fec + 18;
1778        }
1779
1780        inversion |= (tpnode->rolloff << 2) | inversion; // use bit 2..3 of inversion for rolloff
1781        inversion |= (tpnode->pilot << 4) | inversion; // use bit 4..5 of inversion for pilot
1782
1783        tuneto.frequency = node->feloffrequency;
1784        tuneto.inversion = inversion;
1785        tuneto.u.qpsk.symbol_rate = tpnode->symbolrate;
1786        tuneto.u.qpsk.fec_inner = fec;
1787
1788        debug(200, "old dvbapi: frequ=%d, inversion=%d, pilot=%d, rolloff=%d, fec=%d, sr=%d modulation=%d, system=%d (%s)", node->feloffrequency, inversion, tpnode->pilot, tpnode->rolloff, fec, tpnode->symbolrate, tpnode->modulation, tpnode->system, node->feshortname);
1789#endif
1790
1791        fediscard(node);
1792
1793#if DVB_API_VERSION >= 5
1794        if((ioctl(node->fd, FE_SET_PROPERTY, &cmdseq)) == -1)
1795        {
1796                perr("FE_SET_PROPERTY");
1797                return 1;
1798        }
1799#else
1800        if(ioctl(node->fd, FE_SET_FRONTEND, &tuneto) == -1)
1801        {
1802                perr("FE_SET_FRONTEND");
1803                return 1;
1804        }
1805#endif
1806
1807        return 0;
1808}
1809
1810int fetunedvbc(struct dvbdev* node, struct transponder* tpnode)
1811{
1812        if(node == NULL || tpnode == NULL)
1813        {
1814                err("NULL detect");
1815                return 1;
1816        }
1817       
1818        int fec = tpnode->fec;
1819        switch(fec)
1820        {
1821                case 0: fec = FEC_AUTO; break;
1822                case 1: fec = FEC_1_2; break;
1823                case 2: fec = FEC_2_3; break;
1824                case 3: fec = FEC_3_4; break;
1825                case 4: fec = FEC_5_6; break;
1826                case 5: fec = FEC_7_8; break;
1827                case 6: fec = FEC_8_9; break;
1828                case 7: fec = FEC_3_5; break;
1829                case 8: fec = FEC_4_5; break;
1830                case 9: fec = FEC_9_10; break;
1831                case 15: fec = FEC_NONE; break;
1832                default: fec = FEC_AUTO; break;
1833        }
1834
1835        int modulation = tpnode->modulation;
1836        switch(modulation)
1837        {
1838                case 0: modulation = QAM_AUTO; break;
1839                case 1: modulation = QAM_16; break;
1840                case 2: modulation = QAM_32; break;
1841                case 3: modulation = QAM_64; break;
1842                case 4: modulation = QAM_128; break;
1843                case 5: modulation = QAM_256; break;
1844                default: modulation = QAM_AUTO; break;
1845        }
1846
1847#if DVB_API_VERSION >= 5
1848        struct dtv_property p[8];
1849        struct dtv_properties cmdseq;
1850        cmdseq.props = p;
1851       
1852        int system = tpnode->system;
1853       
1854#if DREAMBOX
1855        switch(system)
1856        {
1857                //case 0: system = SYS_DVBC_ANNEX_A; break;
1858                //case 1: system = SYS_DVBC_ANNEX_C; break;
1859                //default: system = SYS_DVBC_ANNEX_A; break;
1860                case 0: system = 1; break;
1861                case 1: system = 18; break;
1862                default: system = 1; break;
1863        }
1864#endif
1865        p[0].cmd = DTV_CLEAR;
1866        p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
1867        p[2].cmd = DTV_FREQUENCY,       p[2].u.data = tpnode->frequency;
1868        p[3].cmd = DTV_MODULATION,      p[3].u.data = modulation;
1869        p[4].cmd = DTV_SYMBOL_RATE,     p[4].u.data = tpnode->symbolrate;
1870        p[5].cmd = DTV_INVERSION,       p[5].u.data = (fe_spectral_inversion_t) tpnode->inversion;
1871        p[6].cmd = DTV_INNER_FEC,       p[6].u.data = fec;
1872        p[7].cmd = DTV_TUNE;
1873        cmdseq.num = 8;
1874
1875        debug(200, "new dvbapi: frequ=%d, inversion=%d, fec=%d, sr=%d, modulation=%d, system=%d (%s)", tpnode->frequency, tpnode->inversion, fec, tpnode->symbolrate, modulation, tpnode->system, node->feshortname);
1876#else
1877        struct dvb_frontend_parameters tuneto;
1878        tuneto.frequency = tpnode->frequency;
1879        tuneto.inversion = tpnode->inversion;
1880        tuneto.u.qam.symbol_rate = tpnode->symbolrate;
1881        tuneto.u.qam.fec_inner = tpnode->fec;
1882        tuneto.u.qam.modulation = tpnode->modulation;
1883
1884        debug(200, "old dvbapi: frequ=%d, inversion=%d, fec=%d, sr=%d, modulation=%d (%s)", tpnode->frequency, tpnode->inversion, fec, tpnode->symbolrate, modulation, node->feshortname);
1885#endif
1886
1887        fediscard(node);
1888
1889#if DVB_API_VERSION >= 5
1890        if((ioctl(node->fd, FE_SET_PROPERTY, &cmdseq)) == -1)
1891        {
1892                perr("FE_SET_PROPERTY");
1893                return 1;
1894        }
1895#else
1896        if(ioctl(node->fd, FE_SET_FRONTEND, &tuneto) == -1)
1897        {
1898                perr("FE_SET_FRONTEND");
1899                return 1;
1900        }
1901#endif
1902
1903        return 0;
1904}
1905
1906int fetunedvbt(struct dvbdev* node, struct transponder* tpnode)
1907{
1908        if(node == NULL || tpnode == NULL)
1909        {
1910                err("NULL detect");
1911                return 1;
1912        }
1913        debug(200, "transponder:frequ=%d, inversion=%d, bandwidth=%d, hp=%d, lp=%d, modulation=%d transmission=%d guardinterval=%d hierarchy=%d system=%d (%s)", tpnode->frequency, tpnode->inversion, tpnode->symbolrate, tpnode->fec, tpnode->polarization, tpnode->modulation, tpnode->pilot, tpnode->rolloff, tpnode->system, tpnode->system, node->feshortname);
1914       
1915        int system = tpnode->system;
1916       
1917        int hp = tpnode->fec; //fec = hp on DVBT
1918        switch(hp)
1919        {
1920                case T_FEC_1_2: hp = FEC_1_2; break;
1921                case T_FEC_2_3: hp = FEC_2_3; break;
1922                case T_FEC_3_4: hp = FEC_3_4; break;
1923                case T_FEC_5_6: hp = FEC_5_6; break;
1924                case T_FEC_6_7: hp = FEC_6_7; break;   
1925                case T_FEC_7_8: hp = FEC_7_8; break;
1926                case T_FEC_8_9: hp = FEC_8_9; break;
1927                default: hp = FEC_AUTO; break;
1928        }
1929
1930        int lp = tpnode->polarization; //polarization = lp on DVBT
1931        switch(lp)
1932        {
1933                case T_FEC_1_2: lp = FEC_1_2; break;
1934                case T_FEC_2_3: lp = FEC_2_3; break;
1935                case T_FEC_3_4: lp = FEC_3_4; break;
1936                case T_FEC_5_6: lp = FEC_5_6; break;
1937                case T_FEC_6_7: lp = FEC_6_7; break;   
1938                case T_FEC_7_8: lp = FEC_7_8; break;
1939                case T_FEC_8_9: lp = FEC_8_9; break;
1940                default: lp = FEC_AUTO; break;
1941        }
1942
1943        int modulation = tpnode->modulation;
1944        switch(modulation)
1945        {
1946                case T_Modulation_QPSK: modulation = QPSK; break;
1947                case T_Modulation_QAM16: modulation = QAM_16; break;
1948                case T_Modulation_QAM64: modulation = QAM_64; break;
1949                case T_Modulation_QAM256: modulation = QAM_256; break;
1950                default: modulation = QAM_AUTO; break;
1951        }
1952
1953        int bandwidth = tpnode->symbolrate; //symbolrate = bandwidth on DVBT
1954        switch(bandwidth)
1955        {
1956                case T_Bandwidth_8MHz: bandwidth = 8000000; break;
1957                case T_Bandwidth_7MHz: bandwidth = 7000000; break;
1958                case T_Bandwidth_6MHz: bandwidth = 6000000; break;
1959                case T_Bandwidth_5MHz: bandwidth = 5000000; break;
1960                case T_Bandwidth_1_712MHz: bandwidth = 1712000; break;
1961                case T_Bandwidth_10MHz: bandwidth = 10000000; break;   
1962                case T_Bandwidth_Auto: bandwidth = 0; break;
1963                default: bandwidth = 0; break;
1964        }
1965       
1966        int transmission = tpnode->pilot; //pilot = transmission on DVBT
1967        switch(transmission)
1968        {
1969                case T_TransmissionMode_2k: transmission = TRANSMISSION_MODE_2K; break;
1970                case T_TransmissionMode_4k: transmission = TRANSMISSION_MODE_4K; break;
1971                case T_TransmissionMode_8k: transmission = TRANSMISSION_MODE_8K; break;
1972                case T_TransmissionMode_Auto: transmission = TRANSMISSION_MODE_AUTO; break;
1973#if defined TRANSMISSION_MODE_1K
1974                case T_TransmissionMode_1k: transmission = TRANSMISSION_MODE_1K; break;
1975                case T_TransmissionMode_16k: transmission = TRANSMISSION_MODE_16K; break;
1976                case T_TransmissionMode_32k: transmission = TRANSMISSION_MODE_32K; break;
1977#endif
1978                default: transmission = TRANSMISSION_MODE_AUTO; break;
1979        }
1980
1981        int guardinterval = tpnode->rolloff; //rolloff = guardinterval on DVBT
1982        switch(guardinterval)
1983        {
1984                case T_GuardInterval_1_32: guardinterval = GUARD_INTERVAL_1_32; break;
1985                case T_GuardInterval_1_16: guardinterval = GUARD_INTERVAL_1_16; break;
1986                case T_GuardInterval_1_8: guardinterval = GUARD_INTERVAL_1_8; break;
1987                case T_GuardInterval_1_4: guardinterval = GUARD_INTERVAL_1_4; break;
1988                case T_GuardInterval_Auto: guardinterval = GUARD_INTERVAL_AUTO; break;
1989#if defined GUARD_INTERVAL_1_128
1990                case T_GuardInterval_1_128: guardinterval = GUARD_INTERVAL_1_128; break;
1991                case T_GuardInterval_19_128: guardinterval = GUARD_INTERVAL_19_128; break;
1992                case T_GuardInterval_19_256: guardinterval = GUARD_INTERVAL_19_256; break;
1993#endif
1994                default: guardinterval = GUARD_INTERVAL_AUTO; break;
1995        }
1996       
1997        int hierarchy = tpnode->system; //system = hierarchy on DVBT
1998        if(tpnode->system == System_DVB_T2) //system = DVB-T2 then hierarchy = HIERARCHY_AUTO
1999                hierarchy = T_Hierarchy_Auto;
2000       
2001        switch(hierarchy)
2002        {
2003                case T_Hierarchy_None: hierarchy = HIERARCHY_NONE;
2004                case T_Hierarchy_1: hierarchy = HIERARCHY_1;
2005                case T_Hierarchy_2: hierarchy = HIERARCHY_2;
2006                case T_Hierarchy_4: hierarchy = HIERARCHY_4;
2007                case T_Hierarchy_Auto: hierarchy = HIERARCHY_AUTO;
2008                default: hierarchy = HIERARCHY_AUTO; break;
2009        }
2010
2011        int ret = 0;
2012        fediscard(node);
2013
2014#if DVB_API_VERSION >= 5
2015        struct dtv_property p[12];
2016        struct dtv_properties cmdseq;
2017        cmdseq.props = p;
2018
2019// suchlauf geht an nemesis mit system=0
2020#if DREAMBOX
2021        switch(system)
2022        {
2023                case System_DVB_T: system = SYS_DVBT; break; //3
2024                case System_DVB_T2: system = SYS_DVBT2; break; //16
2025                default: system = SYS_DVBT; break;
2026        }
2027#endif
2028
2029        p[0].cmd = DTV_CLEAR;
2030        p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
2031        p[2].cmd = DTV_FREQUENCY,       p[2].u.data = tpnode->frequency;
2032        p[3].cmd = DTV_INVERSION,       p[3].u.data = (fe_spectral_inversion_t) tpnode->inversion;
2033        p[4].cmd = DTV_BANDWIDTH_HZ, p[4].u.data = bandwidth;
2034        p[5].cmd = DTV_CODE_RATE_LP, p[5].u.data = lp;
2035        p[6].cmd = DTV_CODE_RATE_HP, p[6].u.data = hp;
2036        p[7].cmd = DTV_MODULATION, p[7].u.data = modulation;
2037        p[8].cmd = DTV_TRANSMISSION_MODE,       p[8].u.data = transmission;
2038        p[9].cmd = DTV_GUARD_INTERVAL, p[9].u.data = guardinterval;
2039        p[10].cmd = DTV_HIERARCHY, p[10].u.data = hierarchy;
2040        p[11].cmd = DTV_TUNE;
2041        cmdseq.num = 12;
2042       
2043        if((ioctl(node->fd, FE_SET_PROPERTY, &cmdseq)) == -1)
2044        {
2045                perr("FE_SET_PROPERTY");
2046                ret = 1;
2047        }
2048
2049        debug(200, "new dvbapi 1: frequ=%d, inversion=%d, bandwidth=%d, hp=%d, lp=%d, modulation=%d transmission=%d guardinterval=%d hierarchy=%d system=%d (%s)", tpnode->frequency, tpnode->inversion, bandwidth, hp, lp, modulation, transmission, guardinterval, hierarchy, system, node->feshortname);
2050
2051#else
2052        struct dvb_frontend_parameters tuneto;
2053
2054        tuneto.frequency = tpnode->frequency;
2055        tuneto.inversion = tpnode->inversion;
2056        tuneto.u.ofdm.bandwidth = bandwidth;
2057        tuneto.u.ofdm.code_rate_HP = hp;
2058        tuneto.u.ofdm.code_rate_LP = lp;
2059        tuneto.u.ofdm.constellation = modulation;
2060        tuneto.u.ofdm.transmission_mode = transmission;
2061        tuneto.u.ofdm.guard_interval = guardinterval;
2062        tuneto.u.ofdm.hierarchy_information = hierarchy;
2063       
2064        if(ioctl(node->fd, FE_SET_FRONTEND, &tuneto) == -1)
2065        {
2066                perr("FE_SET_FRONTEND");
2067                ret = 1;
2068        }
2069
2070        debug(200, "old dvbapi 1: frequ=%d, inversion=%d, bandwidth=%d, hp=%d, lp=%d, modulation=%d transmission=%d guardinterval=%d hierarchy=%d system=%d (%s)", tpnode->frequency, tpnode->inversion, bandwidth, hp, lp, modulation, transmission, guardinterval, hierarchy, system, node->feshortname);
2071
2072#endif
2073        return ret;
2074}
2075
2076#ifdef SIMULATE
2077int tunercount = 0;
2078#endif
2079struct dvb_frontend_info* fegetinfo(struct dvbdev* node, int fd)
2080{
2081        struct dvb_frontend_info* feinfo = NULL;
2082        int tmpfd = -1;
2083
2084        if(node != NULL)
2085                tmpfd = node->fd;
2086        else
2087                tmpfd = fd;
2088
2089        feinfo = (struct dvb_frontend_info*)malloc(sizeof(struct dvb_frontend_info));
2090        if(feinfo == NULL)
2091        {
2092                err("no mem");
2093                return NULL;
2094        }
2095
2096#ifndef SIMULATE
2097        if(ioctl(tmpfd, FE_GET_INFO, feinfo) < 0)
2098        {
2099                perr("FE_GET_INFO");
2100                free(feinfo);
2101                return NULL;
2102        }
2103#else
2104        tunercount++;
2105        if(tunercount == 1)
2106        {
2107                sprintf(feinfo->name, "%s", "Conax 7500 DVB-C");
2108                feinfo->type = FE_QAM;
2109        }
2110        else
2111        {
2112                sprintf(feinfo->name, "%s", "Conax 7500 DVB-S");
2113                feinfo->type = FE_QPSK;
2114                //feinfo->type = FE_QAM;
2115        }
2116#endif
2117        return feinfo;
2118}
2119
2120int fegetdev()
2121{
2122        int i, y, fd = -1, count = 0;
2123        char *buf = NULL, *frontenddev = NULL, *fehyprid = NULL, *tmpstr = NULL, *tmpstr1 = NULL;
2124        struct dvb_frontend_info* feinfo = NULL;
2125        struct dvbdev* dvbnode = NULL;
2126
2127        frontenddev = getconfig("frontenddev", NULL);
2128        if(frontenddev == NULL)
2129        {
2130                err("NULL detect");
2131                return count;
2132        }
2133
2134        buf = malloc(MINMALLOC);
2135        if(buf == NULL)
2136        {
2137                err("no memory");
2138                return count;
2139        }
2140
2141        for(i = 0; i < MAXDVBADAPTER; i++)
2142        {
2143                for(y = 0; y < MAXFRONTENDDEV; y++)
2144                {
2145                        sprintf(buf, frontenddev, i, y);
2146                        fd = feopen(NULL, buf);
2147                        if(fd >= 0)
2148                        {
2149                                fehyprid = gethypridtunerchoicesvalue(y);
2150                                if(fehyprid != NULL)
2151                                {
2152                                        if(y < 10)
2153                                                tmpstr = ostrcat(tmpstr, "fe_0", 1, 0);
2154                                        else
2155                                                tmpstr = ostrcat(tmpstr, "fe_1", 1, 0);
2156
2157                                        tmpstr = ostrcat(tmpstr, oitoa(y), 1, 1);
2158                                        tmpstr = ostrcat(tmpstr, "_hyprid", 1, 0);
2159                                        tmpstr1 = ostrcat(tmpstr, "_last", 0, 0);
2160                                        addconfig(tmpstr1, "999"); //first set
2161                                        free(tmpstr1), tmpstr1 = NULL;
2162#ifndef MIPSEL
2163                                        if(getconfig(tmpstr, NULL) != NULL)
2164                                                sethypridtuner(y, getconfig(tmpstr, NULL));
2165                                        free(tmpstr), tmpstr = NULL;
2166#endif
2167                                }
2168                               
2169                                feinfo = fegetinfo(NULL, fd);
2170                                if(feinfo != NULL)
2171                                {
2172                                        count++;
2173                                        dvbnode = adddvbdev(buf, i, y, fd, FRONTENDDEV, feinfo, NULL, fehyprid, 0);
2174#ifdef MIPSEL
2175                                        if(fehyprid != NULL && getconfig(tmpstr, NULL) != NULL)
2176                                                sethypridtunernew(dvbnode, getconfig(tmpstr, NULL));
2177                                        free(tmpstr), tmpstr = NULL;
2178#endif                                 
2179                                        if(dvbnode->feinfo->type == FE_QPSK)
2180                                                fesetvoltage(dvbnode, SEC_VOLTAGE_OFF, 15);
2181                                               
2182                                        if(y < 10)
2183                                                tmpstr = ostrcat(tmpstr, "fe_0", 1, 0);
2184                                        else
2185                                                tmpstr = ostrcat(tmpstr, "fe_1", 1, 0);
2186                                        tmpstr = ostrcat(tmpstr, oitoa(y), 1, 1);
2187                                        tmpstr = ostrcat(tmpstr, "_fbc", 1, 0);
2188                                        if(ostrstr(feinfo->name, "BCM45208") != NULL) //fbc Tuner
2189                                        {
2190                                                if(getconfig(tmpstr, NULL) == NULL)
2191                                                        addconfig(tmpstr, "A");
2192                                        }
2193                                        else
2194                                                addconfig(tmpstr, "");
2195                                        free(tmpstr), tmpstr = NULL;
2196                                }
2197                        }
2198                }
2199        }
2200
2201        free(buf);
2202        return count;
2203}
2204
2205int fecreatedummy()
2206{
2207        //create dummy frontend for playback
2208        char *buf = NULL, *frontenddev = NULL;
2209        struct dvbdev* dvbnode = NULL;
2210
2211        frontenddev = getconfig("frontenddev", NULL);
2212        if(frontenddev == NULL)
2213        {
2214                err("NULL detect");
2215                return 1;
2216        }
2217
2218        buf = malloc(MINMALLOC);
2219        if(buf == NULL)
2220        {
2221                err("no memory");
2222                return 1;
2223        }
2224
2225        dvbnode = dmxgetlast(0);
2226        if(dvbnode != NULL)
2227        {
2228                sprintf(buf, frontenddev, 0, dvbnode->devnr);
2229                adddvbdev(buf, 0, dvbnode->devnr, -1, FRONTENDDEVDUMMY, NULL, NULL, NULL, 0);
2230        }
2231
2232        free(buf);
2233        return 0;
2234}
2235
2236int fegetlock(int tunernr)
2237{
2238        struct dvbdev* dvbnode = NULL;
2239        dvbnode = dvbdev;
2240
2241        while(dvbnode != NULL)
2242        {
2243                if(dvbnode->deactive == 1)
2244                {
2245                        dvbnode = dvbnode->next;
2246                        continue;
2247                }
2248                if(dvbnode->type == FRONTENDDEV && dvbnode->devnr == tunernr)
2249                {
2250                        return dvbnode->felock;
2251                }
2252                dvbnode = dvbnode->next;
2253        }
2254        return -1;
2255}
2256
2257#ifdef MIPSEL
2258int fechangetype(struct dvbdev* tuner, char* value)
2259{
2260#if DVB_API_VERSION >= 5       
2261
2262        struct dtv_property p[2];
2263        memset(p, 0, sizeof(p));
2264        struct dtv_properties cmdseq;
2265        cmdseq.props = p;
2266        cmdseq.num = 2;
2267        p[0].cmd = DTV_CLEAR;
2268        p[1].cmd = DTV_DELIVERY_SYSTEM;
2269        p[1].u.data = SYS_UNDEFINED;
2270        char* buf = NULL, *hypridtuner = NULL;
2271        int type = 0;
2272        int ret = 0;
2273        char* realname = gethypridtunerchoicesvaluename(tuner->devnr, value);
2274       
2275       
2276        printf("**** > realname: %s\n", realname);
2277       
2278        if(realname != NULL && ostrstr(realname, "DVB-S") != NULL)
2279                type = feSatellite;
2280        else if(realname != NULL && ostrstr(realname, "DVB-C") != NULL)
2281                type = feCable;
2282        else if(realname != NULL && ostrstr(realname, "DVB-T") != NULL)
2283                type = feTerrestrial;
2284        else
2285                type = -1;
2286       
2287        switch (type)
2288        {
2289                case feSatellite:
2290                {
2291                        p[1].u.data = SYS_DVBS;
2292                        break;
2293                }
2294                case feTerrestrial:
2295                {
2296                        //fesetvoltage(tuner, SEC_VOLTAGE_OFF, 10);
2297                        //to do set voltage --> wenn der Tuner es kann
2298                        //fesetvoltage(tuner, SEC_VOLTAGE_13, 10);
2299                        if(realname != NULL && ostrstr(realname, "DVB-T2") != NULL)
2300                                p[1].u.data = SYS_DVBT2;
2301                        else
2302                                p[1].u.data = SYS_DVBT;
2303                        break;
2304                }
2305                case feCable:
2306                {
2307                         fesetvoltage(tuner, SEC_VOLTAGE_OFF, 10);
2308#ifdef SYS_DVBC_ANNEX_A
2309                        p[1].u.data = SYS_DVBC_ANNEX_A;
2310#else
2311                        p[1].u.data = SYS_DVBC_ANNEX_AC;
2312#endif
2313                        break;
2314                }
2315#ifdef feATSC
2316                case feATSC:
2317                {
2318                        p[1].u.data = SYS_ATSC;
2319                        break;
2320                }
2321#endif
2322                default:
2323                        debug(200, "not supported delivery system type %i", type);
2324                        return 0; //false
2325        }
2326        debug(200, "data %d",p[1].u.data );
2327        if (ioctl(tuner->fd, FE_SET_PROPERTY, &cmdseq) == -1)
2328        {
2329                err("FE_SET_PROPERTY failed -> use procfs to switch delivery system tuner %d mode %s type %d",tuner->devnr ,value, type);
2330        }
2331                hypridtuner = getconfig("hypridtuner", NULL);
2332                if(hypridtuner != NULL)
2333                {
2334                        buf = malloc(MINMALLOC);
2335                        if(buf == NULL)
2336                        {
2337                                err("no memory");
2338                                return 0;
2339                        }
2340                }
2341                sprintf(buf, hypridtuner, tuner->devnr);
2342                if(file_exist(buf))
2343                {
2344                        if(tuner->fd > -1)
2345                        {
2346                                feclose(tuner, -1);
2347                                ret = writesys(buf, value, 0);
2348                                tuner->fd = feopen(tuner, NULL);
2349                        }
2350                        else
2351                                ret = writesys(buf, value, 0);
2352                        printf("set %s to %s RC:%i\n", buf, value, ret);
2353                }
2354                else
2355                        err("set system tuner to %d ... file not found -> %s", value, buf);
2356                free(buf); buf = NULL;
2357                return 1; //true
2358       
2359        return 0; //true
2360
2361#else //if DVB_API_VERSION < 5
2362        printf("Hinweis -> DVB API kleiner Version 5\n");
2363        if(sethypridtuner(tuner, value) == 0)
2364                return 1;
2365        return 0; //false
2366#endif
2367}               
2368#endif
2369       
2370
2371#endif
Note: See TracBrowser for help on using the repository browser.