source: titan/titan/frontenddev.h @ 26727

Last change on this file since 26727 was 24741, checked in by gost, 10 years ago

[titan] fix rectimer

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