source: titan/titan/frontenddev.h @ 41048

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

fix

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