source: titan/titan/frontenddev.h @ 40805

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

fix

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