#include "api.h"
#include "tcp.h"
#include "input.h"
+#include "epggrab.h" //Needed to get the next EPG grab times
+#include "dvr/dvr.h" //Needed to get the next schedule dvr time
static int
api_status_inputs
return 0;
}
+static int
+api_status_activity
+ ( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
+{
+ htsmsg_t *cats;
+ time_t temp_earliest = 0;
+ time_t temp_dvr = 0;
+ time_t temp_ota = 0;
+ time_t temp_int = 0;
+ time_t temp_mux = 0;
+ th_subscription_t *ths;
+ uint32_t subscriptionCount = 0;
+
+ temp_dvr = dvr_entry_find_earliest();
+
+ //Only evaluate the OTA grabber cron if there are active OTA modules.
+ if(epggrab_count_type(EPGGRAB_OTA))
+ {
+ temp_ota = epggrab_get_next_ota();
+ }
+
+ //Only evaluate the internal grabber cron if there are active internal modules.
+ if(epggrab_count_type(EPGGRAB_INT))
+ {
+ temp_int = epggrab_get_next_int();
+ }
+
+ temp_mux = mpegts_mux_sched_next();
+
+ temp_earliest = temp_dvr;
+
+ if(temp_ota && ((temp_ota < temp_earliest) || (temp_earliest == 0)))
+ {
+ temp_earliest = temp_ota;
+ }
+
+ if(temp_int && ((temp_int < temp_earliest) || (temp_earliest == 0)))
+ {
+ temp_earliest = temp_int;
+ }
+
+ if(temp_mux && ((temp_mux < temp_earliest) || (temp_earliest == 0)))
+ {
+ temp_earliest = temp_mux;
+ }
+
+ cats = htsmsg_create_map();
+ htsmsg_add_s64(cats, "dvr", temp_dvr);
+ htsmsg_add_s64(cats, "ota_grabber", temp_ota);
+ htsmsg_add_s64(cats, "int_grabber", temp_int);
+ htsmsg_add_s64(cats, "mux_scheduler", temp_mux);
+
+ tvh_mutex_lock(&global_lock);
+ LIST_FOREACH(ths, &subscriptions, ths_global_link) {
+ subscriptionCount++;
+ }
+ tvh_mutex_unlock(&global_lock);
+
+ *resp = htsmsg_create_map();
+ htsmsg_add_s64(*resp, "current_time", gclk());
+ htsmsg_add_s64(*resp, "next_activity", temp_earliest);
+ htsmsg_add_msg(*resp, "activities", cats);
+ htsmsg_add_u32(*resp, "subscription_count", subscriptionCount);
+ htsmsg_add_u32(*resp, "connection_count", tcp_server_connections_count());
+
+ return 0;
+
+}
+
void api_status_init ( void )
{
static api_hook_t ah[] = {
{ "status/subscriptions", ACCESS_ADMIN, api_status_subscriptions, NULL },
{ "status/inputs", ACCESS_ADMIN, api_status_inputs, NULL },
{ "status/inputclrstats", ACCESS_ADMIN, api_status_input_clear_stats, NULL },
+ { "status/activity", ACCESS_ADMIN, api_status_activity, NULL },
{ "connections/cancel", ACCESS_ADMIN, api_connections_cancel, NULL },
{ NULL },
};
dvr_entry_t *dvr_entry_find_by_id(int id);
+time_t dvr_entry_find_earliest(void);
+
static inline dvr_entry_t *dvr_entry_find_by_uuid(const char *uuid)
{ return (dvr_entry_t*)idnode_find(uuid, &dvr_entry_class, NULL); }
return de;
}
+/**
+ * Find the earliest scheduled dvr entry
+ */
+time_t
+dvr_entry_find_earliest(void)
+{
+ time_t start;
+ time_t earliest = 0;
+ dvr_entry_t *de;
+
+ LIST_FOREACH(de, &dvrentries, de_global_link)
+ {
+ if(dvr_entry_is_upcoming(de) && de->de_enabled)
+ {
+ start = dvr_entry_get_start_time(de, 1);
+ if(earliest == 0)
+ {
+ earliest = start;
+ }
+ else if(start < earliest)
+ {
+ earliest = start;
+ }
+ }
+ }//END FOREACH
+
+ return earliest;
+
+}
/**
* Unconditionally remove an entry
}
};
+/* **************************************************************************
+ * Get the time for the next scheduled internal grabber
+ * *************************************************************************/
+time_t epggrab_get_next_int(void)
+{
+ time_t ret_time;
+ struct timespec current_time;
+
+ clock_gettime(CLOCK_REALTIME, ¤t_time);
+ if(!cron_multi_next(epggrab_cron_multi, current_time.tv_sec, &ret_time))
+ {
+ return ret_time;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
+/* **************************************************************************
+ * Count the number of EPG grabbers of a specified type
+ * *************************************************************************/
+int epggrab_count_type(int grabberType)
+{
+ epggrab_module_t *mod;
+ int temp_count = 0;
+
+ LIST_FOREACH(mod, &epggrab_modules, link) {
+ if(mod->enabled && mod->type == grabberType)
+ {
+ temp_count++;
+ }
+ }
+
+ return temp_count;
+
+}
+
/* **************************************************************************
* Initialisation
* *************************************************************************/
*/
extern unsigned char *epggrab_ota_genre_translation;
+/*
+ * Get the next execution times
+ */
+time_t epggrab_get_next_int(void);
+time_t epggrab_get_next_ota(void);
+/*
+ * Count active grabbers for a given type
+ */
+int epggrab_count_type(int grabberType);
+
#endif /* __EPGGRAB_H__ */
/* **************************************************************************
tvh_mutex_unlock(&epggrab_ota_mutex);
}
+/* **************************************************************************
+ * Get the time for the next scheduled ota grabber
+ * *************************************************************************/
+time_t epggrab_get_next_ota(void)
+{
+ time_t ret_time = 0;
+
+ if(!cron_multi_next(epggrab_ota_cron_multi, gclk(), &ret_time))
+ {
+ return ret_time;
+ }
+ else
+ {
+ return 0;
+ }
+}
+
/******************************************************************************
* Editor Configuration
*
tvh_mutex_unlock(&global_lock);
}
+/*
+ * Earliest Mux scheduler
+ */
+time_t mpegts_mux_sched_next(void)
+{
+ time_t earliest = 0;
+ mpegts_mux_sched_t *mms;
+
+ LIST_FOREACH(mms, &mpegts_mux_sched_all, mms_link)
+ {
+ if(mms->mms_enabled) //Only process 'enabled' items.
+ {
+ if(!earliest)
+ {
+ earliest = mms->mms_start;
+ }
+ else if(mms->mms_start < earliest)
+ {
+ earliest = mms->mms_start;
+ }
+ }
+ }//END FOREACH
+
+ return earliest;
+
+}
+
/******************************************************************************
* Editor Configuration
*
void mpegts_mux_sched_init ( void );
void mpegts_mux_sched_done ( void );
+time_t mpegts_mux_sched_next(void);
#endif /* __TVH_MPEGTS_H__ */
return m;
}
+/*
+ * Connections count
+ */
+int
+tcp_server_connections_count ( void )
+{
+ tcp_server_launch_t *tsl;
+ int c = 0;
+
+ /* Count connections */
+ LIST_FOREACH(tsl, &tcp_server_launches, link) {
+ if (!tsl->status) continue;
+ c++;
+ }
+
+ return c;
+}
/**
*
*/
void tcp_connection_cancel_all(void);
htsmsg_t *tcp_server_connections ( void );
+int tcp_server_connections_count ( void );
#endif /* TCP_H_ */