1 /*
2 * tvheadend, charset list
3 * Copyright (C) 2014 Jaroslav Kysela
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 */
18
19 #include "tvheadend.h"
20 #include "settings.h"
21 #include "bouquet.h"
22 #include "dvb.h"
23 #include "fastscan.h"
24
25 #if ENABLE_MPEGTS_DVB
26
27 typedef struct dvb_fastscan_item {
28 LIST_ENTRY(dvb_fastscan_item) ilink;
29
30 const char *name;
31 int pid;
32
33 } dvb_fastscan_item_t;
34
35 typedef struct dvb_fastscan {
36 RB_ENTRY(dvb_fastscan) link;
37
38 LIST_HEAD(,dvb_fastscan_item) items;
39
40 int position;
41 dvb_fe_delivery_system_t delsys;
42 dvb_polarisation_t polarisation;
43 uint32_t frequency;
44 uint32_t symbolRate;
45 } dvb_fastscan_t;
46
47 static RB_HEAD(,dvb_fastscan) fastscan_rb;
48 static SKEL_DECLARE(fastscan_rb_skel, dvb_fastscan_t);
49
50 static int
_fs_cmp(const void * a,const void * b)51 _fs_cmp(const void *a, const void *b)
52 {
53 int r = ((dvb_fastscan_t *)a)->position - ((dvb_fastscan_t *)b)->position;
54 if (r == 0) {
55 r = ((dvb_fastscan_t *)a)->frequency - ((dvb_fastscan_t *)b)->frequency;
56 if (abs(r) < 2000)
57 return (((dvb_fastscan_t *)a)->polarisation - ((dvb_fastscan_t *)b)->polarisation);
58 }
59 return r;
60 }
61
62 void
dvb_fastscan_each(void * aux,int position,uint32_t frequency,dvb_polarisation_t polarisation,void (* job)(void * aux,bouquet_t * bq,const char * name,int pid))63 dvb_fastscan_each(void *aux, int position, uint32_t frequency, dvb_polarisation_t polarisation,
64 void (*job)(void *aux, bouquet_t *bq,
65 const char *name, int pid))
66 {
67 dvb_fastscan_t *fs;
68 dvb_fastscan_item_t *fsi;
69 bouquet_t *bq;
70 char url[64], buf[16];
71
72 SKEL_ALLOC(fastscan_rb_skel);
73 fastscan_rb_skel->position = position;
74 fastscan_rb_skel->frequency = frequency;
75 fastscan_rb_skel->polarisation = polarisation;
76 fs = RB_FIND(&fastscan_rb, fastscan_rb_skel, link, _fs_cmp);
77 if (!fs)
78 return;
79 LIST_FOREACH(fsi, &fs->items, ilink) {
80 dvb_sat_position_to_str(fs->position, buf, sizeof(buf));
81 snprintf(url, sizeof(url), "dvb-fastscan://%s,%s,%u,%s,%u,%d", dvb_delsys2str(fastscan_rb_skel->delsys),
82 buf, fs->frequency, dvb_pol2str(fs->polarisation), fs->symbolRate, fsi->pid);
83 bq = bouquet_find_by_source(NULL, url, 0);
84 if (bq == NULL || !bq->bq_enabled)
85 continue;
86 bq->bq_shield = 1;
87 job(aux, bq, fsi->name, fsi->pid);
88 }
89 }
90
91 static void
dvb_fastscan_create(htsmsg_t * e)92 dvb_fastscan_create(htsmsg_t *e)
93 {
94 dvb_fastscan_t *fs;
95 dvb_fastscan_item_t *fsi;
96 bouquet_t *bq;
97 const char *name, *polarisation, *delsys;
98 int pid;
99 char url[64], buf[16];
100
101 SKEL_ALLOC(fastscan_rb_skel);
102 if (htsmsg_get_s32(e, "position", &fastscan_rb_skel->position))
103 goto fail;
104 if (htsmsg_get_u32(e, "frequency", &fastscan_rb_skel->frequency))
105 goto fail;
106 if (htsmsg_get_s32(e, "pid", &pid))
107 goto fail;
108 if ((name = htsmsg_get_str(e, "name")) == NULL)
109 goto fail;
110 if (htsmsg_get_u32(e, "symbolrate", &fastscan_rb_skel->symbolRate))
111 goto fail;
112 if ((delsys = htsmsg_get_str(e, "delsys")) == NULL)
113 goto fail;
114 if ((polarisation = htsmsg_get_str(e, "polarisation")) == NULL)
115 goto fail;
116
117 fastscan_rb_skel->polarisation = dvb_str2pol(polarisation);
118 fastscan_rb_skel->delsys = dvb_str2delsys(delsys);
119 dvb_sat_position_to_str(fastscan_rb_skel->position, buf, sizeof(buf));
120 snprintf(url, sizeof(url), "dvb-fastscan://%s,%s,%u,%s,%u,%d", dvb_delsys2str(fastscan_rb_skel->delsys),
121 buf, fastscan_rb_skel->frequency, dvb_pol2str(fastscan_rb_skel->polarisation), fastscan_rb_skel->symbolRate, pid);
122 bq = bouquet_find_by_source(name, url, 1);
123 if (bq == NULL)
124 goto fail;
125 bq->bq_shield = 1;
126 if (bq->bq_saveflag) {
127 bq->bq_saveflag = 0;
128 idnode_changed(&bq->bq_id);
129 }
130
131 fs = RB_INSERT_SORTED(&fastscan_rb, fastscan_rb_skel, link, _fs_cmp);
132 if (!fs) {
133 fs = fastscan_rb_skel;
134 SKEL_USED(fastscan_rb_skel);
135 LIST_INIT(&fs->items);
136 }
137
138 fsi = calloc(1, sizeof(*fsi));
139 fsi->pid = pid;
140 if ((fsi->name = htsmsg_get_str(e, "name")) == NULL)
141 goto fail;
142 fsi->name = strdup(name);
143
144 LIST_INSERT_HEAD(&fs->items, fsi, ilink);
145
146 return;
147
148 fail:
149 tvhwarn(LS_FASTSCAN, "wrong entry format");
150 }
151
152 /*
153 * Initialize the fastscan list
154 */
dvb_fastscan_init(void)155 void dvb_fastscan_init ( void )
156 {
157 htsmsg_t *c, *e;
158 htsmsg_field_t *f;
159
160 if (!(c = hts_settings_load("fastscan"))) {
161 tvhwarn(LS_FASTSCAN, "configuration file missing");
162 return;
163 }
164
165 HTSMSG_FOREACH(f, c) {
166 if (!(e = htsmsg_field_get_map(f))) continue;
167 dvb_fastscan_create(e);
168 }
169 htsmsg_destroy(c);
170 }
171
172 /*
173 *
174 */
dvb_fastscan_done(void)175 void dvb_fastscan_done ( void )
176 {
177 dvb_fastscan_t *fs;
178 dvb_fastscan_item_t *fsi;
179
180 while ((fs = RB_FIRST(&fastscan_rb)) != NULL) {
181 RB_REMOVE(&fastscan_rb, fs, link);
182 while ((fsi = LIST_FIRST(&fs->items)) != NULL) {
183 LIST_REMOVE(fsi, ilink);
184 free((char *)fsi->name);
185 free(fsi);
186 }
187 free(fs);
188 }
189 SKEL_FREE(fastscan_rb_skel);
190 }
191
192 #else
193
dvb_fastscan_init(void)194 void dvb_fastscan_init ( void )
195 {
196 }
197
dvb_fastscan_done(void)198 void dvb_fastscan_done ( void )
199 {
200 }
201
202 #endif
203