source: titan/titan/frontenddev.h @ 40788

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

fix last change

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