Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
service mapper: move to simple idnode, add 'create type based tags', …
…fixes #3363
  • Loading branch information
perexg committed Dec 9, 2015
1 parent 593c596 commit def7c48
Show file tree
Hide file tree
Showing 8 changed files with 302 additions and 232 deletions.
30 changes: 3 additions & 27 deletions src/api/api_service.c
Expand Up @@ -27,30 +27,6 @@
#include "api.h"
#include "notify.h"

static int
api_mapper_start
( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
{
service_mapper_conf_t conf = { 0 };
htsmsg_t *uuids;
#define get_u32(x)\
conf.x = htsmsg_get_bool_or_default(args, #x, 0)

/* Get config */
uuids = htsmsg_get_list(args, "uuids");
get_u32(check_availability);
get_u32(encrypted);
get_u32(merge_same_name);
get_u32(provider_tags);
get_u32(network_tags);

pthread_mutex_lock(&global_lock);
service_mapper_start(&conf, uuids);
pthread_mutex_unlock(&global_lock);

return 0;
}

static int
api_mapper_stop
( access_t *perm, void *opaque, const char *op, htsmsg_t *args, htsmsg_t **resp )
Expand Down Expand Up @@ -188,11 +164,11 @@ void api_service_init ( void )
{
extern const idclass_t service_class;
static api_hook_t ah[] = {
{ "service/mapper/start", ACCESS_ADMIN, api_mapper_start, NULL },
{ "service/mapper/load", ACCESS_ADMIN, api_idnode_load_simple, &service_mapper_conf },
{ "service/mapper/save", ACCESS_ADMIN, api_idnode_save_simple, &service_mapper_conf },
{ "service/mapper/stop", ACCESS_ADMIN, api_mapper_stop, NULL },
{ "service/mapper/status", ACCESS_ADMIN, api_mapper_status, NULL },
{ "service/list", ACCESS_ADMIN, api_idnode_load_by_class,
(void*)&service_class },
{ "service/list", ACCESS_ADMIN, api_idnode_load_by_class, (void*)&service_class },
{ "service/streams", ACCESS_ADMIN, api_service_streams, NULL },
{ NULL },
};
Expand Down
3 changes: 2 additions & 1 deletion src/prop.c
Expand Up @@ -271,7 +271,8 @@ prop_read_value
/* List */
if (p->islist) {
assert(p->get); /* requirement */
htsmsg_add_msg(m, name, (htsmsg_t*)val);
if (val)
htsmsg_add_msg(m, name, (htsmsg_t*)val);

/* Single */
} else {
Expand Down
196 changes: 167 additions & 29 deletions src/service_mapper.c
Expand Up @@ -43,29 +43,10 @@ typedef struct service_mapper_item {
static service_mapper_status_t service_mapper_stat;
static pthread_cond_t service_mapper_cond;
static TAILQ_HEAD(, service_mapper_item) service_mapper_queue;
service_mapper_t service_mapper_conf;

static void *service_mapper_thread ( void *p );

/**
* Initialise
*/
pthread_t service_mapper_tid;

void
service_mapper_init ( void )
{
TAILQ_INIT(&service_mapper_queue);
pthread_cond_init(&service_mapper_cond, NULL);
tvhthread_create(&service_mapper_tid, NULL, service_mapper_thread, NULL, "svcmap");
}

void
service_mapper_done ( void )
{
pthread_cond_signal(&service_mapper_cond);
pthread_join(service_mapper_tid, NULL);
}

/*
* Get status
*/
Expand All @@ -78,7 +59,7 @@ service_mapper_status ( void )
/*
* Start a new mapping
*/
void
static void
service_mapper_start ( const service_mapper_conf_t *conf, htsmsg_t *uuids )
{
int e, tr, qd = 0;
Expand Down Expand Up @@ -256,14 +237,16 @@ service_mapper_process
service_mapper_link(s, chn, chn);

/* Type tags */
if (service_is_hdtv(s)) {
channel_tag_map(channel_tag_find_by_name("TV channels", 1), chn, chn);
channel_tag_map(channel_tag_find_by_name("HDTV", 1), chn, chn);
} else if (service_is_sdtv(s)) {
channel_tag_map(channel_tag_find_by_name("TV channels", 1), chn, chn);
channel_tag_map(channel_tag_find_by_name("SDTV", 1), chn, chn);
} else if (service_is_radio(s)) {
channel_tag_map(channel_tag_find_by_name("Radio", 1), chn, chn);
if (conf->type_tags) {
if (service_is_hdtv(s)) {
channel_tag_map(channel_tag_find_by_name("TV channels", 1), chn, chn);
channel_tag_map(channel_tag_find_by_name("HDTV", 1), chn, chn);
} else if (service_is_sdtv(s)) {
channel_tag_map(channel_tag_find_by_name("TV channels", 1), chn, chn);
channel_tag_map(channel_tag_find_by_name("SDTV", 1), chn, chn);
} else if (service_is_radio(s)) {
channel_tag_map(channel_tag_find_by_name("Radio", 1), chn, chn);
}
}

/* Custom tags */
Expand Down Expand Up @@ -434,3 +417,158 @@ service_mapper_reset_stats (void)
service_mapper_stat.fail = 0;
service_mapper_stat.active = NULL;
}

/*
* Save settings
*/
static void service_mapper_conf_class_save ( idnode_t *self )
{
htsmsg_t *m;

m = htsmsg_create_map();
idnode_save(&service_mapper_conf.idnode, m);
hts_settings_save(m, "service_mapper/config");
htsmsg_destroy(m);

if (!htsmsg_is_empty(service_mapper_conf.services))
service_mapper_start(&service_mapper_conf.d, service_mapper_conf.services);
htsmsg_destroy(service_mapper_conf.services);
service_mapper_conf.services = NULL;
}

/*
* Class
*/

static const void *
service_mapper_services_get ( void *obj )
{
return NULL;
}

static char *
service_mapper_services_rend ( void *obj, const char *lang )
{
return strdup("");
}

static int
service_mapper_services_set ( void *obj, const void *p )
{
service_mapper_t *sm = obj;
htsmsg_destroy(sm->services);
sm->services = htsmsg_copy((htsmsg_t *)p);
return 1;
}

static htsmsg_t *
service_mapper_services_enum ( void *obj, const char *lang )
{
htsmsg_t *e, *m = htsmsg_create_map();
htsmsg_add_str(m, "type", "api");
htsmsg_add_str(m, "uri", "service/list");
htsmsg_add_str(m, "event", "service");
e = htsmsg_create_map();
htsmsg_add_bool(e, "enum", 1);
htsmsg_add_msg(m, "params", e);
return m;
}

static const idclass_t service_mapper_conf_class = {
.ic_snode = &service_mapper_conf.idnode,
.ic_class = "service_mapper",
.ic_caption = N_("Service mapper"),
.ic_event = "service_mapper",
.ic_perm_def = ACCESS_ADMIN,
.ic_save = service_mapper_conf_class_save,
.ic_properties = (const property_t[]){
{
.type = PT_STR,
.islist = 1,
.id = "services",
.name = N_("Services"),
.get = service_mapper_services_get,
.set = service_mapper_services_set,
.list = service_mapper_services_enum,
.rend = service_mapper_services_rend
},
{
.type = PT_BOOL,
.id = "check_availability",
.name = N_("Check availability"),
.off = offsetof(service_mapper_t, d.check_availability),
.opts = PO_ADVANCED
},
{
.type = PT_BOOL,
.id = "encrypted",
.name = N_("Map encrypted services"),
.off = offsetof(service_mapper_t, d.encrypted),
},
{
.type = PT_BOOL,
.id = "merge_same_name",
.name = N_("Merge same name"),
.off = offsetof(service_mapper_t, d.merge_same_name),
},
{
.type = PT_BOOL,
.id = "type_tags",
.name = N_("Create type based tags"),
.desc = N_("Create SDTV/HDTV/Radio tags"),
.off = offsetof(service_mapper_t, d.type_tags),
.opts = PO_ADVANCED
},
{
.type = PT_BOOL,
.id = "provider_tags",
.name = N_("Create provider name tags"),
.off = offsetof(service_mapper_t, d.provider_tags),
.opts = PO_ADVANCED
},
{
.type = PT_BOOL,
.id = "network_tags",
.name = N_("Create network name tags"),
.off = offsetof(service_mapper_t, d.network_tags),
.opts = PO_ADVANCED
},
{}
}
};

/*
*
*/

pthread_t service_mapper_tid;

void service_mapper_init ( void )
{
htsmsg_t *m;

TAILQ_INIT(&service_mapper_queue);
pthread_cond_init(&service_mapper_cond, NULL);
tvhthread_create(&service_mapper_tid, NULL, service_mapper_thread, NULL, "svcmap");

/* Defaults */
memset(&service_mapper_conf, 0, sizeof(service_mapper_conf));
service_mapper_conf.idnode.in_class = &service_mapper_conf_class;
service_mapper_conf.d.type_tags = 1;
service_mapper_conf.d.encrypted = 1;

/* Load settings */
if ((m = hts_settings_load("service_mapper/config"))) {
idnode_load(&service_mapper_conf.idnode, m);
htsmsg_destroy(m);
}
}


void service_mapper_done ( void )
{
pthread_cond_signal(&service_mapper_cond);
pthread_join(service_mapper_tid, NULL);
htsmsg_destroy(service_mapper_conf.services);
service_mapper_conf.services = NULL;
}
23 changes: 14 additions & 9 deletions src/service_mapper.h
Expand Up @@ -23,13 +23,20 @@ struct bouquet;

typedef struct service_mapper_conf
{
uint8_t check_availability; ///< Check service is receivable
uint8_t encrypted; ///< Include encrypted services
uint8_t merge_same_name; ///< Merge entries with the same name
uint8_t provider_tags; ///< Create tags based on provider name
uint8_t network_tags; ///< Create tags based on network name (useful for multi adapter equipments)
int check_availability; ///< Check service is receivable
int encrypted; ///< Include encrypted services
int merge_same_name; ///< Merge entries with the same name
int type_tags; ///< Create tags based on the service type (SDTV/HDTV/Radio)
int provider_tags; ///< Create tags based on provider name
int network_tags; ///< Create tags based on network name (useful for multi adapter equipments)
} service_mapper_conf_t;

typedef struct service_mapper {
idnode_t idnode;
service_mapper_conf_t d;
htsmsg_t *services;
} service_mapper_t;

typedef struct service_mapper_status
{
int total;
Expand All @@ -39,13 +46,11 @@ typedef struct service_mapper_status
service_t *active;
} service_mapper_status_t;

extern service_mapper_t service_mapper_conf;

void service_mapper_init ( void );
void service_mapper_done ( void );

// Start new mapping
void service_mapper_start
( const service_mapper_conf_t *conf, htsmsg_t *uuids );

// Stop pending services (remove from Q)
void service_mapper_stop ( void );

Expand Down

0 comments on commit def7c48

Please sign in to comment.