source: titan/titan/frontenddev.h @ 15280

Last change on this file since 15280 was 14784, checked in by nit, 12 years ago

[titan] change all frequency and symbolrate to unsigned int

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