mpegts: added the ability to delete muxes
This commit is contained in:
parent
0d74894f33
commit
c2723dd7cf
9 changed files with 165 additions and 9 deletions
|
@ -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);
|
||||
}
|
||||
|
||||
/* **************************************************************************
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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',
|
||||
|
|
Loading…
Add table
Reference in a new issue