source: titan/titan/frontenddev.h @ 41059

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

[titan] fix loop tuner

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