1 /*
2  *  EPG Grabber - common functions
3  *  Copyright (C) 2012 Adam Sutton
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 #ifndef __EPGGRAB_H__
20 #define __EPGGRAB_H__
21 
22 #include "idnode.h"
23 
24 #include <pthread.h>
25 
26 /* **************************************************************************
27  * Typedefs/Forward decls
28  * *************************************************************************/
29 
30 typedef struct epggrab_module       epggrab_module_t;
31 typedef struct epggrab_module_int   epggrab_module_int_t;
32 typedef struct epggrab_module_ext   epggrab_module_ext_t;
33 typedef struct epggrab_module_ota   epggrab_module_ota_t;
34 typedef struct epggrab_ota_mux      epggrab_ota_mux_t;
35 typedef struct epggrab_ota_map      epggrab_ota_map_t;
36 typedef struct epggrab_ota_svc_link epggrab_ota_svc_link_t;
37 
38 LIST_HEAD(epggrab_module_list, epggrab_module);
39 typedef struct epggrab_module_list epggrab_module_list_t;
40 
41 struct mpegts_mux;
42 struct channel;
43 
44 /* **************************************************************************
45  * Grabber Stats
46  * *************************************************************************/
47 
48 typedef struct epggrab_stats_part
49 {
50   int created;
51   int modified;
52   int total;
53 } epggrab_stats_part_t;
54 
55 typedef struct epggrab_stats
56 {
57   epggrab_stats_part_t channels;
58   epggrab_stats_part_t brands;
59   epggrab_stats_part_t seasons;
60   epggrab_stats_part_t episodes;
61   epggrab_stats_part_t broadcasts;
62   epggrab_stats_part_t config;
63 } epggrab_stats_t;
64 
65 /* **************************************************************************
66  * Grabber Channels
67  * *************************************************************************/
68 
69 /*
70  * Lists
71  */
72 RB_HEAD(epggrab_channel_tree, epggrab_channel);
73 typedef struct epggrab_channel_tree epggrab_channel_tree_t;
74 
75 TAILQ_HEAD(epggrab_channel_queue, epggrab_channel);
76 
77 /*
78  * Grab channel
79  */
80 typedef struct epggrab_channel
81 {
82   idnode_t                  idnode;
83   TAILQ_ENTRY(epggrab_channel) all_link; ///< Global link
84   RB_ENTRY(epggrab_channel) link;     ///< Global tree link
85   epggrab_module_t          *mod;     ///< Linked module
86 
87   int                       updated;  ///< EPG channel was updated
88   int                       enabled;  ///< Enabled/disabled
89   char                      *id;      ///< Grabber's ID
90 
91   char                      *name;    ///< Channel name
92   htsmsg_t                  *names;   ///< List of all channel names for grabber's ID
93   htsmsg_t                  *newnames;///< List of all channel names for grabber's ID (scan)
94   char                      *icon;    ///< Channel icon
95   char                      *comment; ///< Channel comment (EPG)
96   int64_t                   lcn;      ///< Channel number (split)
97 
98   time_t                    laststamp;///< Last update timestamp
99 
100   int                       only_one; ///< Map to only one channel (auto)
101   idnode_list_head_t        channels; ///< Mapped channels (1 = epggrab channel, 2 = channel)
102 
103   int                       update_chicon; ///< Update channel icon
104   int                       update_chnum;  ///< Update channel number
105   int                       update_chname; ///< Update channel name
106 } epggrab_channel_t;
107 
108 /*
109  * Access functions
110  */
111 htsmsg_t *epggrab_channel_list      ( int ota );
112 
113 /*
114  * Mutators
115  */
116 int epggrab_channel_set_name     ( epggrab_channel_t *ch, const char *name );
117 int epggrab_channel_set_icon     ( epggrab_channel_t *ch, const char *icon );
118 int epggrab_channel_set_number   ( epggrab_channel_t *ch, int major, int minor );
119 
120 /*
121  * Updated/link
122  */
123 void epggrab_channel_updated     ( epggrab_channel_t *ch );
124 void epggrab_channel_link_delete ( epggrab_channel_t *ec, struct channel *ch, int delconf );
125 int  epggrab_channel_link        ( epggrab_channel_t *ec, struct channel *ch, void *origin );
126 int  epggrab_channel_map         ( idnode_t *ec, idnode_t *ch, void *origin );
127 
128 /* ID */
129 const char *epggrab_channel_get_id ( epggrab_channel_t *ch );
130 epggrab_channel_t *epggrab_channel_find_by_id ( const char *id );
131 
132 /*
133  * Check type
134  */
135 int epggrab_channel_is_ota ( epggrab_channel_t *ec );
136 
137 /* **************************************************************************
138  * Grabber Modules
139  * *************************************************************************/
140 
141 /*
142  * Grabber base class
143  */
144 struct epggrab_module
145 {
146   idnode_t                     idnode;
147   LIST_ENTRY(epggrab_module)   link;      ///< Global list link
148 
149   enum {
150     EPGGRAB_OTA,
151     EPGGRAB_INT,
152     EPGGRAB_EXT,
153   }                            type;      ///< Grabber type
154   const char                   *id;       ///< Module identifier
155   int                          subsys;    ///< Module log subsystem
156   const char                   *saveid;   ///< Module save identifier
157   const char                   *name;     ///< Module name (for display)
158   int                          enabled;   ///< Whether the module is enabled
159   int                          active;    ///< Whether the module is active
160   int                          priority;  ///< Priority of the module
161   epggrab_channel_tree_t       channels;  ///< Channel list
162 
163   /* Activate */
164   int       (*activate) ( void *m, int activate );
165 
166   /* Free */
167   void      (*done)    ( void *m );
168 };
169 
170 /*
171  * Internal grabber
172  */
173 struct epggrab_module_int
174 {
175   epggrab_module_t             ;          ///< Parent object
176 
177   const char                   *path;     ///< Path for the command
178   const char                   *args;     ///< Extra arguments
179 
180   int                           xmltv_chnum;
181 
182   /* Handle data */
183   char*     (*grab)   ( void *mod );
184   htsmsg_t* (*trans)  ( void *mod, char *data );
185   int       (*parse)  ( void *mod, htsmsg_t *data, epggrab_stats_t *stat );
186 };
187 
188 /*
189  * External grabber
190  */
191 struct epggrab_module_ext
192 {
193   epggrab_module_int_t         ;          ///< Parent object
194 
195   int                          sock;      ///< Socket descriptor
196 
197   pthread_t                    tid;       ///< Thread ID
198 };
199 
200 struct epggrab_ota_svc_link
201 {
202   char                          *uuid;
203   uint64_t                       last_tune_count;
204   RB_ENTRY(epggrab_ota_svc_link) link;
205 };
206 
207 /*
208  * TODO: this could be embedded in the mux itself, but by using a soft-link
209  *       and keeping it here I can somewhat isolate it from the mpegts code
210  */
211 struct epggrab_ota_mux
212 {
213   char                              *om_mux_uuid;     ///< Soft-link to mux
214   LIST_HEAD(,epggrab_ota_map)        om_modules;      ///< List of linked mods
215 
216   uint8_t                            om_done;         ///< The full completion mark for this round
217   uint8_t                            om_complete;     ///< Has completed a scan
218   uint8_t                            om_requeue;      ///< Requeue when stolen
219   uint8_t                            om_save;         ///< something changed
220   mtimer_t                           om_timer;        ///< Per mux active timer
221   mtimer_t                           om_data_timer;   ///< Any EPG data seen?
222   int64_t                            om_retry_time;   ///< Next time to retry
223 
224   char                              *om_force_modname;///< Force this module
225 
226   enum {
227     EPGGRAB_OTA_MUX_IDLE,
228     EPGGRAB_OTA_MUX_PENDING,
229     EPGGRAB_OTA_MUX_ACTIVE
230   }                                  om_q_type;
231 
232   TAILQ_ENTRY(epggrab_ota_mux)       om_q_link;
233   RB_ENTRY(epggrab_ota_mux)          om_global_link;
234 };
235 
236 /*
237  * Link between ota_mux and ota_module
238  */
239 struct epggrab_ota_map
240 {
241   LIST_ENTRY(epggrab_ota_map)         om_link;
242   epggrab_module_ota_t               *om_module;
243   int                                 om_complete;
244   uint8_t                             om_first;
245   uint8_t                             om_forced;
246   uint64_t                            om_tune_count;
247   RB_HEAD(,epggrab_ota_svc_link)      om_svcs;         ///< Muxes we carry data for
248 };
249 
250 /*
251  * Over the air grabber
252  */
253 struct epggrab_module_ota
254 {
255   epggrab_module_t               ;      ///< Parent object
256 
257   /* Transponder tuning */
258   int  (*start) ( epggrab_ota_map_t *map, struct mpegts_mux *mm );
259   int  (*tune)  ( epggrab_ota_map_t *map, epggrab_ota_mux_t *om,
260                   struct mpegts_mux *mm );
261   void  *opaque;
262 };
263 
264 /*
265  *
266  */
267 typedef struct epggrab_conf {
268   idnode_t              idnode;
269   char                 *cron;
270   uint32_t              channel_rename;
271   uint32_t              channel_renumber;
272   uint32_t              channel_reicon;
273   uint32_t              epgdb_periodicsave;
274   uint32_t              epgdb_saveafterimport;
275   char                 *ota_cron;
276   uint32_t              ota_timeout;
277   uint32_t              ota_initial;
278 } epggrab_conf_t;
279 
280 /*
281  *
282  */
283 extern epggrab_conf_t epggrab_conf;
284 extern const idclass_t epggrab_class;
285 extern const idclass_t epggrab_class_mod;
286 extern const idclass_t epggrab_class_mod_int;
287 extern const idclass_t epggrab_class_mod_ext;
288 extern const idclass_t epggrab_class_mod_ota;
289 extern const idclass_t epggrab_channel_class;
290 extern struct epggrab_channel_queue epggrab_channel_entries;
291 
292 /*
293  * Access the Module list
294  */
295 epggrab_module_t* epggrab_module_find_by_id ( const char *id );
296 const char * epggrab_module_type(epggrab_module_t *mod);
297 const char * epggrab_module_get_status(epggrab_module_t *mod);
298 
299 /* **************************************************************************
300  * Setup/Configuration
301  * *************************************************************************/
302 
303 /*
304  * Configuration
305  */
306 extern epggrab_module_list_t epggrab_modules;
307 extern pthread_mutex_t       epggrab_mutex;
308 extern int                   epggrab_running;
309 extern int                   epggrab_ota_running;
310 
311 /*
312  * Set configuration
313  */
314 int epggrab_activate_module       ( epggrab_module_t *mod, int activate );
315 void epggrab_ota_set_cron         ( void );
316 void epggrab_ota_trigger          ( int secs );
317 void epggrab_rerun_internal       ( void );
318 
319 /*
320  * Load/Save
321  */
322 void epggrab_init                 ( void );
323 void epggrab_done                 ( void );
324 void epggrab_ota_init             ( void );
325 void epggrab_ota_post             ( void );
326 void epggrab_ota_shutdown         ( void );
327 
328 /* **************************************************************************
329  * Global Functions
330  * *************************************************************************/
331 
332 /*
333  * Channel handling
334  */
335 void epggrab_channel_add ( struct channel *ch );
336 void epggrab_channel_rem ( struct channel *ch );
337 void epggrab_channel_mod ( struct channel *ch );
338 
339 /*
340  * Re-schedule
341  */
342 void epggrab_resched     ( void );
343 
344 /*
345  * OTA kick
346  */
347 void epggrab_ota_queue_mux( struct mpegts_mux *mm );
348 
349 #endif /* __EPGGRAB_H__ */
350 
351 /* **************************************************************************
352  * Editor
353  *
354  * vim:sts=2:ts=2:sw=2:et
355  * *************************************************************************/
356