source: titan/titan/frontenddev.h @ 40813

Last change on this file since 40813 was 40813, checked in by gost, 7 years ago

[titan] DVB-T2 fix

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       
1246#ifdef ARM
1247//#ifdef MIPSEL
1248        int signalquality = 0;
1249        int signalqualitydb = 0;
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        if(!signalquality && !signalqualitydb)
1269        {
1270                int ret = 0x12345678;
1271                int sat_max = 1600; // we assume a max of 16db here
1272                int ter_max = 2900; // we assume a max of 29db here
1273                int cab_max = 4200; // we assume a max of 42db here
1274                //int atsc_max = 4200; // we assume a max of 42db here
1275               
1276                ioctl(node->fd, FE_READ_SNR, &snr);
1277                               
1278                if(ostrstr(node->feinfo->name, "Si2166B") != NULL)
1279                {
1280                        ret = (snr * 240) >> 8;
1281                }
1282                else if (ostrstr(node->feinfo->name, "ATBM781x") != NULL)
1283                {
1284                        ret = snr*10;
1285                }
1286                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)
1287                {
1288                        ret = (snr * 100) >> 8;
1289                }
1290                else if (ostrstr(node->feinfo->name, "Si216") != NULL) // all new Models with SI Tuners
1291                {
1292                        ret = snr;
1293                }
1294                signalqualitydb = ret;
1295                if (ret == 0x12345678) // no snr db calculation avail.. return untouched snr value..
1296                {
1297                        signalquality = snr;
1298                }
1299                if(node->feinfo->type == FE_QPSK)
1300                        signalquality = (ret >= sat_max ? 65536 : ret * 65536 / sat_max);
1301                else if(node->feinfo->type == FE_QAM)
1302                        signalquality = (ret >= cab_max ? 65536 : ret * 65536 / cab_max);
1303                else if(node->feinfo->type == FE_OFDM)
1304                        signalquality = (ret >= ter_max ? 65536 : ret * 65536 / ter_max);
1305        }
1306        debug(200, "frontend snr = %02x", (signalquality * 100) / 0xffff);
1307        return signalquality;
1308#else   
1309        ioctl(node->fd, FE_READ_SNR, &snr);
1310        debug(200, "frontend snr = %02x", (snr * 100) / 0xffff);
1311        return snr;
1312#endif
1313       
1314}
1315
1316uint16_t fereadsignalstrength(struct dvbdev* node)
1317{
1318        uint16_t signal = 0;
1319
1320        if(node == NULL)
1321        {
1322                err("NULL detect");
1323                return 0;
1324        }
1325       
1326#ifdef ARM             
1327        struct dtv_property prop[1];
1328        prop[0].cmd = DTV_STAT_SIGNAL_STRENGTH;
1329        struct dtv_properties props;
1330        props.props = prop;
1331        props.num = 1;
1332        ioctl(node->fd, FE_GET_PROPERTY, &props);
1333        for(unsigned int i=0; i<prop[0].u.st.len; i++)
1334        {
1335                if (prop[0].u.st.stat[i].scale == FE_SCALE_RELATIVE)
1336                        signal = prop[0].u.st.stat[i].uvalue;
1337        }
1338        if (!signal)
1339        {
1340                ioctl(node->fd, FE_READ_SIGNAL_STRENGTH, &signal);
1341                if(ostrstr(node->feinfo->name, "Si2166B") != NULL)
1342                        signal = signal * 1000;
1343                debug(200, "frontend signal = %02x", (signal * 100) / 0xffff);
1344        }
1345        return signal;
1346#else   
1347        ioctl(node->fd, FE_READ_SIGNAL_STRENGTH, &signal);
1348        debug(200, "frontend signal = %02x", (signal * 100) / 0xffff);
1349        return signal;
1350#endif
1351}
1352
1353uint32_t fereadber(struct dvbdev* node)
1354{
1355        uint32_t ber = 0;
1356
1357        if(node == NULL)
1358        {
1359                err("NULL detect");
1360                return 0;
1361        }
1362
1363        ioctl(node->fd, FE_READ_BER, &ber);
1364        debug(200, "frontend ber = %02x", ber);
1365        return ber;
1366}
1367
1368uint32_t fereaduncorrectedblocks(struct dvbdev* node)
1369{
1370        uint32_t unc = 0;
1371
1372        if(node == NULL)
1373        {
1374                err("NULL detect");
1375                return 0;
1376        }
1377
1378        ioctl(node->fd, FE_READ_UNCORRECTED_BLOCKS, &unc);
1379        debug(200, "frontend unc = %02x", unc);
1380        return unc;
1381}
1382
1383fe_status_t fereadstatus(struct dvbdev* node)
1384{
1385        fe_status_t status;
1386
1387        if(node == NULL)
1388        {
1389                err("NULL detect");
1390                return -1;
1391        }
1392
1393        if(ioctl(node->fd, FE_READ_STATUS, &status) == -1)
1394                perr("FE_READ_STATUS");
1395
1396        debug(200, "frontend status = %02x", status);
1397        if(status & FE_HAS_LOCK) debug(200, "frontend = FE_HAS_LOCK");
1398        if(status & FE_HAS_SIGNAL) debug(200, "frontend = FE_HAS_SIGNAL");
1399        if(status & FE_HAS_CARRIER) debug(200, "frontend = FE_HAS_CARRIER");
1400        if(status & FE_HAS_VITERBI) debug(200, "frontend = FE_HAS_VITERBI");
1401        if(status & FE_HAS_SYNC) debug(200, "frontend = FE_HAS_SYNC");
1402        if(status & FE_TIMEDOUT) debug(200, "frontend = FE_TIMEDOUT");
1403        if(status & FE_REINIT) debug(200, "frontend = FE_REINIT");
1404
1405        return status;
1406}
1407
1408int fetunedvbs(struct dvbdev* node, struct transponder* tpnode)
1409{
1410        if(node == NULL || tpnode == NULL)
1411        {
1412                err("NULL detect");
1413                return 1;
1414        }
1415       
1416        if(node->feunicable == 1)
1417        {
1418                fesetunicable(node);
1419                char* tmpstr = ostrcat(node->feshortname, "_lnb_satcrfrequ", 0, 0);
1420                node->feloffrequency = getconfigint(tmpstr, node->feaktnr) * 1000;
1421                free(tmpstr); tmpstr = NULL;
1422        }
1423
1424#if DVB_API_VERSION >= 5
1425        struct dtv_property p[10];
1426        struct dtv_properties cmdseq;
1427        cmdseq.props = p;
1428
1429        //convert transponderlist for dvbapi5
1430        int system = tpnode->system;
1431        switch(system)
1432        {
1433                case 0: system = SYS_DVBS; break;
1434                case 1: system = SYS_DVBS2; break;
1435                default: system = SYS_DVBS; break;
1436        }
1437
1438        int fec = tpnode->fec;
1439        switch(fec)
1440        {
1441                case 0: fec = FEC_AUTO; break;
1442                case 1: fec = FEC_1_2; break;
1443                case 2: fec = FEC_2_3; break;
1444                case 3: fec = FEC_3_4; break;
1445                case 4: fec = FEC_5_6; break;
1446                case 5: fec = FEC_7_8; break;
1447                case 6: fec = FEC_8_9; break;
1448                case 7: fec = FEC_3_5; break;
1449                case 8: fec = FEC_4_5; break;
1450                case 9: fec = FEC_9_10; break;
1451                case 15: fec = FEC_NONE; break;
1452                default: fec = FEC_AUTO; break;
1453        }
1454       
1455        int pilot = tpnode->pilot;
1456        switch(pilot)
1457        {
1458                case 0: pilot = PILOT_OFF; break;
1459                case 1: pilot = PILOT_ON; break;
1460                case 2: pilot = PILOT_AUTO; break;
1461                default: pilot = PILOT_AUTO; break;
1462        }
1463
1464        int rolloff = tpnode->rolloff;
1465        switch(rolloff)
1466        {
1467                case 0: rolloff = ROLLOFF_35; break;
1468                case 1: rolloff = ROLLOFF_25; break;
1469                case 2: rolloff = ROLLOFF_20; break;
1470                default: rolloff = ROLLOFF_35; break;
1471        }
1472
1473        int modulation = tpnode->modulation;
1474        switch(modulation)
1475        {
1476                case 0: modulation = QPSK; break;
1477                case 1: modulation = QPSK; break;
1478                case 2: modulation = PSK_8; break;
1479                case 3: modulation = QAM_16; break;
1480                default: modulation = QPSK; break;
1481        }
1482
1483        p[0].cmd = DTV_CLEAR;
1484        p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
1485        p[2].cmd = DTV_FREQUENCY,       p[2].u.data = node->feloffrequency;
1486        p[3].cmd = DTV_MODULATION,      p[3].u.data = modulation;
1487        p[4].cmd = DTV_SYMBOL_RATE,     p[4].u.data = tpnode->symbolrate;
1488        p[5].cmd = DTV_INNER_FEC,       p[5].u.data = fec;
1489        p[6].cmd = DTV_INVERSION,       p[6].u.data = (fe_spectral_inversion_t) tpnode->inversion;
1490        if(system == SYS_DVBS2)
1491        {
1492                p[7].cmd = DTV_ROLLOFF,         p[7].u.data = rolloff;
1493                p[8].cmd = DTV_PILOT,           p[8].u.data = pilot;
1494                p[9].cmd = DTV_TUNE;
1495                cmdseq.num = 10;
1496        }
1497        else
1498        {
1499                p[7].cmd = DTV_TUNE;
1500                cmdseq.num = 8;
1501        }
1502
1503        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);
1504#else
1505        struct dvb_frontend_parameters tuneto;
1506        fe_spectral_inversion_t inversion = tpnode->inversion;
1507
1508        //convert transponderlist for dvbapi3
1509        int fec = tpnode->fec;
1510        if(tpnode->system == 1)
1511        {
1512                if(tpnode->modulation == 1) fec = fec + 9;
1513                if(tpnode->modulation == 2) fec = fec + 18;
1514        }
1515
1516        inversion |= (tpnode->rolloff << 2) | inversion; // use bit 2..3 of inversion for rolloff
1517        inversion |= (tpnode->pilot << 4) | inversion; // use bit 4..5 of inversion for pilot
1518
1519        tuneto.frequency = node->feloffrequency;
1520        tuneto.inversion = inversion;
1521        tuneto.u.qpsk.symbol_rate = tpnode->symbolrate;
1522        tuneto.u.qpsk.fec_inner = fec;
1523
1524        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);
1525#endif
1526
1527        fediscard(node);
1528
1529#if DVB_API_VERSION >= 5
1530        if((ioctl(node->fd, FE_SET_PROPERTY, &cmdseq)) == -1)
1531        {
1532                perr("FE_SET_PROPERTY");
1533                return 1;
1534        }
1535#else
1536        if(ioctl(node->fd, FE_SET_FRONTEND, &tuneto) == -1)
1537        {
1538                perr("FE_SET_FRONTEND");
1539                return 1;
1540        }
1541#endif
1542
1543        return 0;
1544}
1545
1546int fetunedvbc(struct dvbdev* node, struct transponder* tpnode)
1547{
1548        if(node == NULL || tpnode == NULL)
1549        {
1550                err("NULL detect");
1551                return 1;
1552        }
1553       
1554        int fec = tpnode->fec;
1555        switch(fec)
1556        {
1557                case 0: fec = FEC_AUTO; break;
1558                case 1: fec = FEC_1_2; break;
1559                case 2: fec = FEC_2_3; break;
1560                case 3: fec = FEC_3_4; break;
1561                case 4: fec = FEC_5_6; break;
1562                case 5: fec = FEC_7_8; break;
1563                case 6: fec = FEC_8_9; break;
1564                case 7: fec = FEC_3_5; break;
1565                case 8: fec = FEC_4_5; break;
1566                case 9: fec = FEC_9_10; break;
1567                case 15: fec = FEC_NONE; break;
1568                default: fec = FEC_AUTO; break;
1569        }
1570
1571        int modulation = tpnode->modulation;
1572        switch(modulation)
1573        {
1574                case 0: modulation = QAM_AUTO; break;
1575                case 1: modulation = QAM_16; break;
1576                case 2: modulation = QAM_32; break;
1577                case 3: modulation = QAM_64; break;
1578                case 4: modulation = QAM_128; break;
1579                case 5: modulation = QAM_256; break;
1580                default: modulation = QAM_AUTO; break;
1581        }
1582
1583#if DVB_API_VERSION >= 5
1584        struct dtv_property p[8];
1585        struct dtv_properties cmdseq;
1586        cmdseq.props = p;
1587       
1588        int system = tpnode->system;
1589       
1590#if DREAMBOX
1591        switch(system)
1592        {
1593                //case 0: system = SYS_DVBC_ANNEX_A; break;
1594                //case 1: system = SYS_DVBC_ANNEX_C; break;
1595                //default: system = SYS_DVBC_ANNEX_A; break;
1596                case 0: system = 1; break;
1597                case 1: system = 18; break;
1598                default: system = 1; break;
1599        }
1600#endif
1601
1602        p[0].cmd = DTV_CLEAR;
1603        p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
1604        p[2].cmd = DTV_FREQUENCY,       p[2].u.data = tpnode->frequency;
1605        p[3].cmd = DTV_MODULATION,      p[3].u.data = modulation;
1606        p[4].cmd = DTV_SYMBOL_RATE,     p[4].u.data = tpnode->symbolrate;
1607        p[5].cmd = DTV_INVERSION,       p[5].u.data = (fe_spectral_inversion_t) tpnode->inversion;
1608        p[6].cmd = DTV_INNER_FEC,       p[6].u.data = fec;
1609        p[7].cmd = DTV_TUNE;
1610        cmdseq.num = 8;
1611
1612        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);
1613#else
1614        struct dvb_frontend_parameters tuneto;
1615
1616        tuneto.frequency = tpnode->frequency;
1617        tuneto.inversion = tpnode->inversion;
1618        tuneto.u.qam.symbol_rate = tpnode->symbolrate;
1619        tuneto.u.qam.fec_inner = tpnode->fec;
1620        tuneto.u.qam.modulation = tpnode->modulation;
1621
1622        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);
1623#endif
1624
1625        fediscard(node);
1626
1627#if DVB_API_VERSION >= 5
1628        if((ioctl(node->fd, FE_SET_PROPERTY, &cmdseq)) == -1)
1629        {
1630                perr("FE_SET_PROPERTY");
1631                return 1;
1632        }
1633#else
1634        if(ioctl(node->fd, FE_SET_FRONTEND, &tuneto) == -1)
1635        {
1636                perr("FE_SET_FRONTEND");
1637                return 1;
1638        }
1639#endif
1640
1641        return 0;
1642}
1643
1644int fetunedvbt(struct dvbdev* node, struct transponder* tpnode)
1645{
1646        if(node == NULL || tpnode == NULL)
1647        {
1648                err("NULL detect");
1649                return 1;
1650        }
1651        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);
1652       
1653        int system = tpnode->system;
1654       
1655        int hp = tpnode->fec; //fec = hp on DVBT
1656        switch(hp)
1657        {
1658                case T_FEC_1_2: hp = FEC_1_2; break;
1659                case T_FEC_2_3: hp = FEC_2_3; break;
1660                case T_FEC_3_4: hp = FEC_3_4; break;
1661                case T_FEC_5_6: hp = FEC_5_6; break;
1662                case T_FEC_6_7: hp = FEC_6_7; break;   
1663                case T_FEC_7_8: hp = FEC_7_8; break;
1664                case T_FEC_8_9: hp = FEC_8_9; break;
1665                default: hp = FEC_AUTO; break;
1666        }
1667
1668        int lp = tpnode->polarization; //polarization = lp on DVBT
1669        switch(lp)
1670        {
1671                case T_FEC_1_2: lp = FEC_1_2; break;
1672                case T_FEC_2_3: lp = FEC_2_3; break;
1673                case T_FEC_3_4: lp = FEC_3_4; break;
1674                case T_FEC_5_6: lp = FEC_5_6; break;
1675                case T_FEC_6_7: lp = FEC_6_7; break;   
1676                case T_FEC_7_8: lp = FEC_7_8; break;
1677                case T_FEC_8_9: lp = FEC_8_9; break;
1678                default: lp = FEC_AUTO; break;
1679        }
1680
1681        int modulation = tpnode->modulation;
1682        switch(modulation)
1683        {
1684                case T_Modulation_QPSK: modulation = QPSK; break;
1685                case T_Modulation_QAM16: modulation = QAM_16; break;
1686                case T_Modulation_QAM64: modulation = QAM_64; break;
1687                case T_Modulation_QAM256: modulation = QAM_256; break;
1688                default: modulation = QAM_AUTO; break;
1689        }
1690
1691        int bandwidth = tpnode->symbolrate; //symbolrate = bandwidth on DVBT
1692        switch(bandwidth)
1693        {
1694                case T_Bandwidth_8MHz: bandwidth = 8000000; break;
1695                case T_Bandwidth_7MHz: bandwidth = 7000000; break;
1696                case T_Bandwidth_6MHz: bandwidth = 6000000; break;
1697                case T_Bandwidth_5MHz: bandwidth = 5000000; break;
1698                case T_Bandwidth_1_712MHz: bandwidth = 1712000; break;
1699                case T_Bandwidth_10MHz: bandwidth = 10000000; break;   
1700                case T_Bandwidth_Auto: bandwidth = 0; break;
1701                default: bandwidth = 0; break;
1702        }
1703       
1704        int transmission = tpnode->pilot; //pilot = transmission on DVBT
1705        switch(transmission)
1706        {
1707                case T_TransmissionMode_2k: transmission = TRANSMISSION_MODE_2K; break;
1708                case T_TransmissionMode_4k: transmission = TRANSMISSION_MODE_4K; break;
1709                case T_TransmissionMode_8k: transmission = TRANSMISSION_MODE_8K; break;
1710                case T_TransmissionMode_Auto: transmission = TRANSMISSION_MODE_AUTO; break;
1711#if defined TRANSMISSION_MODE_1K
1712                case T_TransmissionMode_1k: transmission = TRANSMISSION_MODE_1K; break;
1713                case T_TransmissionMode_16k: transmission = TRANSMISSION_MODE_16K; break;
1714                case T_TransmissionMode_32k: transmission = TRANSMISSION_MODE_32K; break;
1715#endif
1716                default: transmission = TRANSMISSION_MODE_AUTO; break;
1717        }
1718
1719        int guardinterval = tpnode->rolloff; //rolloff = guardinterval on DVBT
1720        switch(guardinterval)
1721        {
1722                case T_GuardInterval_1_32: guardinterval = GUARD_INTERVAL_1_32; break;
1723                case T_GuardInterval_1_16: guardinterval = GUARD_INTERVAL_1_16; break;
1724                case T_GuardInterval_1_8: guardinterval = GUARD_INTERVAL_1_8; break;
1725                case T_GuardInterval_1_4: guardinterval = GUARD_INTERVAL_1_4; break;
1726                case T_GuardInterval_Auto: guardinterval = GUARD_INTERVAL_AUTO; break;
1727#if defined GUARD_INTERVAL_1_128
1728                case T_GuardInterval_1_128: guardinterval = GUARD_INTERVAL_1_128; break;
1729                case T_GuardInterval_19_128: guardinterval = GUARD_INTERVAL_19_128; break;
1730                case T_GuardInterval_19_256: guardinterval = GUARD_INTERVAL_19_256; break;
1731#endif
1732                default: guardinterval = GUARD_INTERVAL_AUTO; break;
1733        }
1734       
1735        int hierarchy = tpnode->system; //system = hierarchy on DVBT
1736        if(tpnode->system == System_DVB_T2) //system = DVB-T2 then hierarchy = HIERARCHY_AUTO
1737                hierarchy = T_Hierarchy_Auto;
1738       
1739        switch(hierarchy)
1740        {
1741                case T_Hierarchy_None: hierarchy = HIERARCHY_NONE;
1742                case T_Hierarchy_1: hierarchy = HIERARCHY_1;
1743                case T_Hierarchy_2: hierarchy = HIERARCHY_2;
1744                case T_Hierarchy_4: hierarchy = HIERARCHY_4;
1745                case T_Hierarchy_Auto: hierarchy = HIERARCHY_AUTO;
1746                default: hierarchy = HIERARCHY_AUTO; break;
1747        }
1748
1749        int ret = 0;
1750        fediscard(node);
1751
1752#if DVB_API_VERSION >= 5
1753        struct dtv_property p[12];
1754        struct dtv_properties cmdseq;
1755        cmdseq.props = p;
1756
1757// suchlauf geht an nemesis mit system=0
1758#if DREAMBOX
1759        switch(system)
1760        {
1761                case System_DVB_T: system = SYS_DVBT; break; //3
1762                case System_DVB_T2: system = SYS_DVBT2; break; //16
1763                default: system = SYS_DVBT; break;
1764        }
1765#endif
1766
1767        p[0].cmd = DTV_CLEAR;
1768        p[1].cmd = DTV_DELIVERY_SYSTEM, p[1].u.data = system;
1769        p[2].cmd = DTV_FREQUENCY,       p[2].u.data = tpnode->frequency;
1770        p[3].cmd = DTV_INVERSION,       p[3].u.data = (fe_spectral_inversion_t) tpnode->inversion;
1771        p[4].cmd = DTV_BANDWIDTH_HZ, p[4].u.data = bandwidth;
1772        p[5].cmd = DTV_CODE_RATE_LP, p[5].u.data = lp;
1773        p[6].cmd = DTV_CODE_RATE_HP, p[6].u.data = hp;
1774        p[7].cmd = DTV_MODULATION, p[7].u.data = modulation;
1775        p[8].cmd = DTV_TRANSMISSION_MODE,       p[8].u.data = transmission;
1776        p[9].cmd = DTV_GUARD_INTERVAL, p[9].u.data = guardinterval;
1777        p[10].cmd = DTV_HIERARCHY, p[10].u.data = hierarchy;
1778        p[11].cmd = DTV_TUNE;
1779        cmdseq.num = 12;
1780       
1781        if((ioctl(node->fd, FE_SET_PROPERTY, &cmdseq)) == -1)
1782        {
1783                perr("FE_SET_PROPERTY");
1784                ret = 1;
1785        }
1786
1787        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);
1788
1789#else
1790        struct dvb_frontend_parameters tuneto;
1791
1792        tuneto.frequency = tpnode->frequency;
1793        tuneto.inversion = tpnode->inversion;
1794        tuneto.u.ofdm.bandwidth = bandwidth;
1795        tuneto.u.ofdm.code_rate_HP = hp;
1796        tuneto.u.ofdm.code_rate_LP = lp;
1797        tuneto.u.ofdm.constellation = modulation;
1798        tuneto.u.ofdm.transmission_mode = transmission;
1799        tuneto.u.ofdm.guard_interval = guardinterval;
1800        tuneto.u.ofdm.hierarchy_information = hierarchy;
1801       
1802        if(ioctl(node->fd, FE_SET_FRONTEND, &tuneto) == -1)
1803        {
1804                perr("FE_SET_FRONTEND");
1805                ret = 1;
1806        }
1807
1808        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);
1809
1810#endif
1811        return ret;
1812}
1813
1814#ifdef SIMULATE
1815int tunercount = 0;
1816#endif
1817struct dvb_frontend_info* fegetinfo(struct dvbdev* node, int fd)
1818{
1819        struct dvb_frontend_info* feinfo = NULL;
1820        int tmpfd = -1;
1821
1822        if(node != NULL)
1823                tmpfd = node->fd;
1824        else
1825                tmpfd = fd;
1826
1827        feinfo = (struct dvb_frontend_info*)malloc(sizeof(struct dvb_frontend_info));
1828        if(feinfo == NULL)
1829        {
1830                err("no mem");
1831                return NULL;
1832        }
1833
1834#ifndef SIMULATE
1835        if(ioctl(tmpfd, FE_GET_INFO, feinfo) < 0)
1836        {
1837                perr("FE_GET_INFO");
1838                free(feinfo);
1839                return NULL;
1840        }
1841#else
1842        tunercount++;
1843        if(tunercount == 1)
1844        {
1845                sprintf(feinfo->name, "%s", "Conax 7500 DVB-C");
1846                feinfo->type = FE_QAM;
1847        }
1848        else
1849        {
1850                sprintf(feinfo->name, "%s", "Conax 7500 DVB-S");
1851                feinfo->type = FE_QPSK;
1852                //feinfo->type = FE_QAM;
1853        }
1854#endif
1855        return feinfo;
1856}
1857
1858int fegetdev()
1859{
1860        int i, y, fd = -1, count = 0;
1861        char *buf = NULL, *frontenddev = NULL, *fehyprid = NULL, *tmpstr = NULL;
1862        struct dvb_frontend_info* feinfo = NULL;
1863        struct dvbdev* dvbnode = NULL;
1864
1865        frontenddev = getconfig("frontenddev", NULL);
1866        if(frontenddev == NULL)
1867        {
1868                err("NULL detect");
1869                return count;
1870        }
1871
1872        buf = malloc(MINMALLOC);
1873        if(buf == NULL)
1874        {
1875                err("no memory");
1876                return count;
1877        }
1878
1879        for(i = 0; i < MAXDVBADAPTER; i++)
1880        {
1881                for(y = 0; y < MAXFRONTENDDEV; y++)
1882                {
1883                        sprintf(buf, frontenddev, i, y);
1884                        fd = feopen(NULL, buf);
1885                        if(fd >= 0)
1886                        {
1887                                fehyprid = gethypridtunerchoicesvalue(y);
1888                                if(fehyprid != NULL)
1889                                {
1890                                        if(y < 10)
1891                                                tmpstr = ostrcat(tmpstr, "fe_0", 1, 0);
1892                                        else
1893                                                tmpstr = ostrcat(tmpstr, "fe_1", 1, 0);
1894
1895                                        tmpstr = ostrcat(tmpstr, oitoa(y), 1, 1);
1896                                        tmpstr = ostrcat(tmpstr, "_hyprid", 1, 0);
1897#ifndef MIPSEL
1898                                        if(getconfig(tmpstr, NULL) != NULL)
1899                                                sethypridtuner(y, getconfig(tmpstr, NULL));
1900                                        free(tmpstr), tmpstr = NULL;
1901#endif
1902                                }
1903                               
1904                                feinfo = fegetinfo(NULL, fd);
1905                                if(feinfo != NULL)
1906                                {
1907                                        count++;
1908                                        dvbnode = adddvbdev(buf, i, y, fd, FRONTENDDEV, feinfo, NULL, fehyprid, 0);
1909#ifdef MIPSEL
1910                                        if(fehyprid != NULL && getconfig(tmpstr, NULL) != NULL)
1911                                                sethypridtunernew(dvbnode, getconfig(tmpstr, NULL));
1912                                        free(tmpstr), tmpstr = NULL;
1913#endif                                 
1914                                        if(dvbnode->feinfo->type == FE_QPSK)
1915                                                fesetvoltage(dvbnode, SEC_VOLTAGE_OFF, 15);
1916                                }
1917                        }
1918                }
1919        }
1920
1921        free(buf);
1922        return count;
1923}
1924
1925int fecreatedummy()
1926{
1927        //create dummy frontend for playback
1928        char *buf = NULL, *frontenddev = NULL;
1929        struct dvbdev* dvbnode = NULL;
1930
1931        frontenddev = getconfig("frontenddev", NULL);
1932        if(frontenddev == NULL)
1933        {
1934                err("NULL detect");
1935                return 1;
1936        }
1937
1938        buf = malloc(MINMALLOC);
1939        if(buf == NULL)
1940        {
1941                err("no memory");
1942                return 1;
1943        }
1944
1945        dvbnode = dmxgetlast(0);
1946        if(dvbnode != NULL)
1947        {
1948                sprintf(buf, frontenddev, 0, dvbnode->devnr);
1949                adddvbdev(buf, 0, dvbnode->devnr, -1, FRONTENDDEVDUMMY, NULL, NULL, NULL, 0);
1950        }
1951
1952        free(buf);
1953        return 0;
1954}
1955
1956int fegetlock(int tunernr)
1957{
1958        struct dvbdev* dvbnode = NULL;
1959        dvbnode = dvbdev;
1960
1961        while(dvbnode != NULL)
1962        {
1963                if(dvbnode->deactive == 1)
1964                {
1965                        dvbnode = dvbnode->next;
1966                        continue;
1967                }
1968                if(dvbnode->type == FRONTENDDEV && dvbnode->devnr == tunernr)
1969                {
1970                        return dvbnode->felock;
1971                }
1972                dvbnode = dvbnode->next;
1973        }
1974        return -1;
1975}
1976
1977#ifdef MIPSEL
1978int fechangetype(struct dvbdev* tuner, char* value)
1979{
1980#if DVB_API_VERSION >= 5       
1981
1982        struct dtv_property p[2];
1983        memset(p, 0, sizeof(p));
1984        struct dtv_properties cmdseq;
1985        cmdseq.props = p;
1986        cmdseq.num = 2;
1987        p[0].cmd = DTV_CLEAR;
1988        p[1].cmd = DTV_DELIVERY_SYSTEM;
1989        p[1].u.data = SYS_UNDEFINED;
1990       
1991        int type = 0;
1992        char* realname = gethypridtunerchoicesvaluename(tuner->devnr, value);
1993       
1994        printf("**** > realname: %s\n", realname);
1995       
1996        if(realname != NULL && ostrstr(realname, "DVB-S") != NULL)
1997                type = feSatellite;
1998        else if(realname != NULL && ostrstr(realname, "DVB-C") != NULL)
1999                type = feCable;
2000        else if(realname != NULL && ostrstr(realname, "DVB-T") != NULL)
2001                type = feTerrestrial;
2002        else
2003                type = -1;
2004       
2005        switch (type)
2006        {
2007                case feSatellite:
2008                {
2009                        p[1].u.data = SYS_DVBS;
2010                        break;
2011                }
2012                case feTerrestrial:
2013                {
2014                        //fesetvoltage(tuner, SEC_VOLTAGE_OFF, 10);
2015                        //to do set voltage --> wenn der Tuner es kann
2016                        //fesetvoltage(tuner, SEC_VOLTAGE_13, 10);
2017                        if(realname != NULL && ostrstr(realname, "DVB-T2") != NULL)
2018                                p[1].u.data = SYS_DVBT2;
2019                        else
2020                                p[1].u.data = SYS_DVBT;
2021                        break;
2022                }
2023                case feCable:
2024                {
2025                         fesetvoltage(tuner, SEC_VOLTAGE_OFF, 10);
2026#ifdef SYS_DVBC_ANNEX_A
2027                        p[1].u.data = SYS_DVBC_ANNEX_A;
2028#else
2029                        p[1].u.data = SYS_DVBC_ANNEX_AC;
2030#endif
2031                        break;
2032                }
2033#ifdef feATSC
2034                case feATSC:
2035                {
2036                        p[1].u.data = SYS_ATSC;
2037                        break;
2038                }
2039#endif
2040                default:
2041                        debug(200, "not supported delivery system type %i", type);
2042                        return 0; //false
2043        }
2044        debug(200, "data %d",p[1].u.data );
2045        if (ioctl(tuner->fd, FE_SET_PROPERTY, &cmdseq) == -1)
2046                err("FE_SET_PROPERTY failed -> system tuner %d mode %s type %d ",tuner->devnr ,value, type);
2047        return 1; //true
2048
2049#else //if DVB_API_VERSION < 5
2050        return 0; //false
2051#endif
2052}               
2053#endif
2054       
2055
2056#endif
Note: See TracBrowser for help on using the repository browser.