mpegts: added the ability to delete muxes

This commit is contained in:
Adam Sutton 2013-08-06 22:22:49 +01:00
parent 0d74894f33
commit c2723dd7cf
9 changed files with 165 additions and 9 deletions

View file

@ -134,6 +134,7 @@ int
idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class)
{
idnode_t *c;
lock_assert(&global_lock);
if(uuid == NULL) {
if(read(randfd, in->in_uuid, 16) != 16) {
perror("read(random for uuid)");
@ -160,7 +161,9 @@ idnode_insert(idnode_t *in, const char *uuid, const idclass_t *class)
void
idnode_unlink(idnode_t *in)
{
lock_assert(&global_lock);
RB_REMOVE(&idnodes, in, in_link);
idnode_updated(in);
}
/* **************************************************************************

View file

@ -247,6 +247,7 @@ struct mpegts_mux
* Functions
*/
void (*mm_delete) (mpegts_mux_t *mm);
void (*mm_config_save) (mpegts_mux_t *mm);
void (*mm_display_name) (mpegts_mux_t*, char *buf, size_t len);
int (*mm_is_enabled) (mpegts_mux_t *mm);
@ -350,6 +351,8 @@ struct mpegts_mux_instance
// TODO: remove this
int mmi_tune_failed; // this is really DVB
void (*mmi_delete) (mpegts_mux_instance_t *mmi);
};
/* Input source */
@ -485,8 +488,16 @@ mpegts_mux_t *mpegts_mux_create0
mpegts_mux_create0(calloc(1, sizeof(mpegts_mux_t)), &mpegts_mux_class, uuid,\
mn, onid, tsid, conf)
#define mpegts_mux_find(u)\
idnode_find(u, &mpegts_mux_class);
#define mpegts_mux_delete_by_uuid(u)\
{ mpegts_mux_t *mm = mpegts_mux_find(u); if (mm) mm->mm_delete(mm); }
void mpegts_mux_initial_scan_done ( mpegts_mux_t *mm );
void mpegts_mux_delete ( mpegts_mux_t *mm );
void mpegts_mux_save ( mpegts_mux_t *mm, htsmsg_t *c );
mpegts_mux_instance_t *mpegts_mux_instance_create0

View file

@ -449,6 +449,20 @@ linuxdvb_mux_close_table ( mpegts_mux_t *mm, mpegts_table_t *mt )
close(mt->mt_fd);
}
static void
linuxdvb_mux_delete
( mpegts_mux_t *mm )
{
printf("delete %p\n", mm);
/* Remove config */
hts_settings_remove("input/linuxdvb/networks/%s/muxes/%s/config",
idnode_uuid_as_str(&mm->mm_network->mn_id),
idnode_uuid_as_str(&mm->mm_id));
/* Delete the mux */
mpegts_mux_delete(mm);
}
/* **************************************************************************
* Creation/Config
* *************************************************************************/
@ -490,6 +504,7 @@ linuxdvb_mux_create0
memcpy(&lm->lm_tuning, dmc, sizeof(dvb_mux_conf_t));
/* Callbacks */
lm->mm_delete = linuxdvb_mux_delete;
lm->mm_display_name = linuxdvb_mux_display_name;
lm->mm_config_save = linuxdvb_mux_config_save;
lm->mm_create_instances = linuxdvb_mux_create_instances;

View file

@ -36,6 +36,16 @@ const idclass_t mpegts_mux_instance_class =
.ic_caption = "MPEGTS Multiplex Phy",
};
static void
mpegts_mux_instance_delete
( mpegts_mux_instance_t *mmi )
{
idnode_unlink(&mmi->mmi_id);
LIST_REMOVE(mmi, mmi_mux_link);
LIST_REMOVE(mmi, mmi_input_link);
free(mmi);
}
mpegts_mux_instance_t *
mpegts_mux_instance_create0
( mpegts_mux_instance_t *mmi, const idclass_t *class, const char *uuid,
@ -47,8 +57,13 @@ mpegts_mux_instance_create0
/* Setup links */
mmi->mmi_mux = mm;
mmi->mmi_input = mi;
/* Callbacks */
mmi->mmi_delete = mpegts_mux_instance_delete;
LIST_INSERT_HEAD(&mm->mm_instances, mmi, mmi_mux_link);
LIST_INSERT_HEAD(&mi->mi_mux_instances, mmi, mmi_input_link);
return mmi;
}
@ -220,6 +235,42 @@ mpegts_mux_display_name ( mpegts_mux_t *mm, char *buf, size_t len )
mm->mm_onid, mm->mm_tsid);
}
void
mpegts_mux_delete ( mpegts_mux_t *mm )
{
mpegts_mux_instance_t *mmi;
mpegts_network_t *mn = mm->mm_network;
mpegts_service_t *s;
char buf[256];
mm->mm_display_name(mm, buf, sizeof(buf));
tvhinfo("mpegts", "%s - deleting", buf);
/* Stop */
mm->mm_stop(mm);
/* Remove from lists */
LIST_REMOVE(mm, mm_network_link);
printf("SCAN STATUS = %d\n", mm->mm_initial_scan_done);
if (mm->mm_initial_scan_status != MM_SCAN_DONE) {
printf("remove from pending Q\n");
TAILQ_REMOVE(&mn->mn_initial_scan_pending_queue, mm, mm_initial_scan_link);
}
while ((mmi = LIST_FIRST(&mm->mm_instances))) {
mmi->mmi_delete(mmi);
}
/* Delete services */
while ((s = LIST_FIRST(&mm->mm_services))) {
service_destroy((service_t*)s);
}
/* Free memory */
idnode_unlink(&mm->mm_id);
free(mm->mm_crid_authority);
free(mm);
}
static void
mpegts_mux_config_save ( mpegts_mux_t *mm )
{
@ -481,6 +532,7 @@ mpegts_mux_create0
mm->mm_network = mn;
/* Debug/Config */
mm->mm_delete = mpegts_mux_delete;
mm->mm_display_name = mpegts_mux_display_name;
mm->mm_config_save = mpegts_mux_config_save;
mm->mm_is_enabled = mpegts_mux_is_enabled;

View file

@ -306,6 +306,21 @@ mpegts_service_provider_name ( service_t *s )
return ((mpegts_service_t*)s)->s_dvb_provider;
}
static void
mpegts_service_delete ( service_t *t )
{
mpegts_service_t *ms = (mpegts_service_t*)t;
free(ms->s_dvb_svcname);
free(ms->s_dvb_provider);
free(ms->s_dvb_charset);
LIST_REMOVE(ms, s_dvb_mux_link);
// TODO: delete config
// Note: the ultimate deletion and removal from the idnode list
// is done in service_destroy
}
/* **************************************************************************
* Creation/Location
* *************************************************************************/
@ -330,6 +345,7 @@ mpegts_service_create0
s->s_dvb_mux = mm;
LIST_INSERT_HEAD(&mm->mm_services, s, s_dvb_mux_link);
s->s_delete = mpegts_service_delete;
s->s_is_enabled = mpegts_service_is_enabled;
s->s_config_save = mpegts_service_config_save;
s->s_enlist = mpegts_service_enlist;

View file

@ -359,8 +359,8 @@ service_destroy(service_t *t)
th_subscription_t *s;
channel_service_mapping_t *csm;
if(t->s_dtor != NULL)
t->s_dtor(t);
if(t->s_delete != NULL)
t->s_delete(t);
lock_assert(&global_lock);

View file

@ -278,7 +278,7 @@ typedef struct service {
int (*s_grace_period)(struct service *t);
void (*s_dtor)(struct service *t);
void (*s_delete)(struct service *t);
/**
* Channel info

View file

@ -166,6 +166,20 @@ extjs_mpegts_service
return 0;
}
static void
http_api_boilerplate
(http_connection_t *hc, const char **op, htsmsg_t **args)
{
const char *s;
*op = http_arg_get(&hc->hc_req_args, "op");
s = http_arg_get(&hc->hc_req_args, "args");
if (s)
*args = htsmsg_json_deserialize(s);
else
*args = NULL;
if (!*op && *args)
*op = htsmsg_get_str(*args, "method"); // HTSP compat
}
static int
extjs_mpegts_mux
@ -173,11 +187,16 @@ extjs_mpegts_mux
{
mpegts_network_t *mn;
mpegts_mux_t *mm;
htsbuf_queue_t *hq = &hc->hc_reply;
const char *op = http_arg_get(&hc->hc_req_args, "op");
htsbuf_queue_t *hq = &hc->hc_reply;
const char *op;
htsmsg_t *args;
htsmsg_t *out = htsmsg_create_map();
extjs_grid_conf_t conf = { 0 };
http_api_boilerplate(hc, &op, &args);
if (!op)
return HTTP_STATUS_BAD_REQUEST;
if (!strcmp(op, "list")) {
idnode_set_t ins = { 0 };
extjs_grid_conf(&hc->hc_req_args, &conf);
@ -191,6 +210,17 @@ extjs_mpegts_mux
} else if (!strcmp(op, "class")) {
htsmsg_t *list = idclass_serialize(&mpegts_mux_class);
htsmsg_add_msg(out, "entries", list);
} else if (!strcmp(op, "delete") && args) {
htsmsg_field_t *f;
htsmsg_t *uuids = htsmsg_get_list(args, "uuids");
if (uuids) {
pthread_mutex_lock(&global_lock);
HTSMSG_FOREACH(f, uuids) {
if (f->hmf_type == HMF_STR)
mpegts_mux_delete_by_uuid(f->hmf_str);
}
pthread_mutex_unlock(&global_lock);
}
}
htsmsg_json_serialize(out, hq, 0);
@ -363,22 +393,32 @@ extjs_mpegts_input
} else if (!strcmp(op, "network_class")) {
const char *uuid = http_arg_get(&hc->hc_req_args, "uuid");
if (!uuid) return 404;
pthread_mutex_lock(&global_lock);
mpegts_input_t *mi = idnode_find(uuid, &mpegts_input_class);
if (!mi) return 404;
if (!mi) {
pthread_mutex_unlock(&global_lock);
return 404;
}
htsmsg_t *list= idclass_serialize(mi->mi_network_class(mi));
htsmsg_add_msg(out, "entries", list);
pthread_mutex_unlock(&global_lock);
} else if (!strcmp(op, "network_create")) {
const char *uuid = http_arg_get(&hc->hc_req_args, "uuid");
const char *conf = http_arg_get(&hc->hc_req_args, "conf");
if (!uuid || !conf) return 404;
pthread_mutex_lock(&global_lock);
mi = idnode_find(uuid, &mpegts_input_class);
if (!mi) return 404;
if (!mi) {
pthread_mutex_unlock(&global_lock);
return 404;
}
mn = mi->mi_network_create(mi, htsmsg_json_deserialize(conf));
if (mn)
mn->mn_config_save(mn);
else {
// TODO: Check for error
}
pthread_mutex_unlock(&global_lock);
#endif
}

View file

@ -4,6 +4,8 @@ json_decode = function(d)
d = Ext.util.JSON.decode(d.responseText)
if (d.entries)
d = d.entries;
if (d.nodes)
d = d.nodes;
} else {
d = []
}
@ -498,7 +500,24 @@ tvheadend.idnode_grid = function(panel, conf)
iconCls : 'remove',
text : 'Delete',
disabled : true,
handler : function(){}
handler : function() {
var r = select.getSelections();
if (r) {
var uuids = []
for ( var i = 0; i < r.length; i++ )
uuids.push(r[i].id)
Ext.Ajax.request({
url : conf.url,
params : {
op: 'delete',
args : Ext.util.JSON.encode({ uuids: uuids})
},
success : function(d)
{
}
});
}
}
});
buttons.push(delBtn);
}
@ -539,7 +558,7 @@ tvheadend.idnode_grid = function(panel, conf)
success : function(d)
{
d = json_decode(d);
var p = tvheadend.idnode_editor(d[0], {});
var p = tvheadend.idnode_editor(d, {});
var w = new Ext.Window({
title : 'Edit ' + conf.titleS,
layout : 'fit',