source: titan/titan/frontenddev.h @ 41054

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

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