source: titan/titan/frontenddev.h @ 39752

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

arm.. fix signal display

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