source: titan/titan/frontenddev.h @ 41113

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

next fix

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