source: titan/titan/frontenddev.h @ 41045

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

[titan] fix looptuner with different satellites

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