source: titan/titan/frontenddev.h @ 40879

Last change on this file since 40879 was 40879, checked in by gost, 5 years ago

[titan] fix sh4 snr

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