summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config.c19
-rw-r--r--node.c31
-rw-r--r--node.h3
-rw-r--r--router.c137
-rw-r--r--router.h5
-rw-r--r--zone.c53
-rw-r--r--zone.h4
7 files changed, 252 insertions, 0 deletions
diff --git a/config.c b/config.c
index 1a74f23..26d725e 100644
--- a/config.c
+++ b/config.c
@@ -20,6 +20,7 @@
*
*/
#include "config.h"
+#include "zone.h"
const char *agl_config_file_get_path (const char *dir, const char *file, char *buf, size_t len)
{
@@ -117,5 +118,23 @@ bool use_default_configuration (struct userdata *u)
typemap_def *t;
prior_def *p;
+ pa_assert (u);
+
+ for (z = zones; z->name; z++)
+ agl_zoneset_add_zone (u, z->name, (uint32_t)(z - zones));
+
+ for (r = rtgroups; r->name; r++)
+ agl_router_create_rtgroup (u, r->type, r->name, r->accept, r->compare);
+
+ for (c = classmap; c->rtgroup; c++)
+ agl_router_assign_class_to_rtgroup (u, c->class, c->zone,
+ c->type, c->rtgroup);
+
+ for (t = typemap; t->id; t++)
+ agl_nodeset_add_role (u, t->id, t->type, NULL);
+
+ for (p = priormap; p->class; p++)
+ agl_router_assign_class_priority (u, p->class, p->priority);
+
return true;
}
diff --git a/node.c b/node.c
index 212a923..e2c5007 100644
--- a/node.c
+++ b/node.c
@@ -68,6 +68,27 @@ void agl_nodeset_done(struct userdata *u)
}
}
+int agl_nodeset_add_role (struct userdata *u, const char *role, agl_node_type type, agl_nodeset_resdef *resdef)
+{
+ agl_nodeset *ns;
+ agl_nodeset_map *map;
+
+ pa_assert (u);
+ pa_assert_se (ns = u->nodeset);
+
+ map = pa_xnew0 (agl_nodeset_map, 1);
+ map->name = pa_xstrdup (role);
+ map->type = type;
+ map->role = pa_xstrdup (role);
+
+ if (resdef) {
+ map->resdef = pa_xnew (agl_nodeset_resdef, 1);
+ memcpy (map->resdef, resdef, sizeof(agl_nodeset_resdef));
+ }
+
+ return pa_hashmap_put (ns->roles, (void *)map->name, map);
+}
+
agl_node *agl_node_create (struct userdata *u, agl_node *data)
{
agl_nodeset *ns;
@@ -132,6 +153,16 @@ const char *agl_node_type_str (agl_node_type type)
}
}
+const char *agl_node_direction_str (agl_direction direction)
+{
+ switch (direction) {
+ case agl_direction_unknown: return "unknown";
+ case agl_input: return "input";
+ case agl_output: return "output";
+ default: return "< ??? >";
+ }
+}
+
agl_node *agl_node_get_from_data (struct userdata *u, agl_direction type, void *data)
{
pa_sink_input_new_data *sinp_data;
diff --git a/node.h b/node.h
index 13f2303..30c375b 100644
--- a/node.h
+++ b/node.h
@@ -101,8 +101,11 @@ struct agl_node {
agl_nodeset *agl_nodeset_init (struct userdata *);
void agl_nodeset_done (struct userdata *);
+int agl_nodeset_add_role (struct userdata *, const char *, agl_node_type, agl_nodeset_resdef *);
+
agl_node *agl_node_create (struct userdata *, agl_node *);
const char *agl_node_type_str (agl_node_type);
+const char *agl_node_direction_str (agl_direction);
agl_node *agl_node_get_from_data (struct userdata *, agl_direction, void *);
agl_node *agl_node_get_from_client (struct userdata *, pa_client *);
diff --git a/router.c b/router.c
index a431b69..fa05d4e 100644
--- a/router.c
+++ b/router.c
@@ -21,6 +21,7 @@
*/
#include "router.h"
#include "switch.h"
+#include "zone.h"
#include "utils.h"
agl_router *agl_router_init (struct userdata *u)
@@ -108,6 +109,142 @@ int agl_router_phone_compare (struct userdata *u, agl_rtgroup *rtg, agl_node *n1
return 1;
}
+agl_rtgroup *agl_router_create_rtgroup (struct userdata *u, agl_direction type, const char *name, agl_rtgroup_accept_t accept, agl_rtgroup_compare_t compare)
+{
+ agl_router *router;
+ agl_rtgroup *rtg;
+ pa_hashmap *table;
+
+ pa_assert (u);
+ pa_assert (type == agl_input || type == agl_output);
+ pa_assert (name);
+ pa_assert (accept);
+ pa_assert (compare);
+ pa_assert_se (router = u->router);
+
+ if (type == agl_input)
+ table = router->rtgroups.input;
+ else
+ table = router->rtgroups.output;
+ pa_assert (table);
+
+ rtg = pa_xnew0 (agl_rtgroup, 1);
+ rtg->name = pa_xstrdup (name);
+ rtg->accept = accept;
+ rtg->compare = compare;
+ AGL_DLIST_INIT(rtg->entries);
+
+ pa_hashmap_put (table, rtg->name, rtg);
+
+ pa_log_debug ("routing group '%s' created", name);
+
+ return rtg;
+}
+
+void agl_router_destroy_rtgroup (struct userdata *u, agl_direction type, const char *name)
+{
+ agl_router *router;
+ agl_rtgroup *rtg;
+ pa_hashmap *table;
+
+ pa_assert (u);
+ pa_assert (name);
+ pa_assert_se (router = u->router);
+
+ if (type == agl_input)
+ table = router->rtgroups.input;
+ else
+ table = router->rtgroups.output;
+ pa_assert (table);
+
+ rtg = pa_hashmap_remove (table, name);
+ if (!rtg) {
+ pa_log_debug ("can't destroy routing group '%s': not found", name);
+ } else {
+ //rtgroup_destroy (u, rtg);
+ pa_log_debug ("routing group '%s' destroyed", name);
+ }
+}
+
+bool agl_router_assign_class_to_rtgroup (struct userdata *u, agl_node_type class, uint32_t zone, agl_direction type, const char *name)
+{
+ agl_router *router;
+ pa_hashmap *rtable;
+ agl_rtgroup ***classmap;
+ agl_rtgroup **zonemap;
+ const char *classname;
+ const char *direction;
+ agl_rtgroup *rtg;
+ agl_zone *rzone;
+
+ pa_assert (u);
+ pa_assert (zone < AGL_ZONE_MAX);
+ pa_assert (type == agl_input || type == agl_output);
+ pa_assert (name);
+ pa_assert_se (router = u->router);
+
+ if (type == agl_input) {
+ rtable = router->rtgroups.input;
+ classmap = router->classmap.input;
+ } else {
+ rtable = router->rtgroups.output;
+ classmap = router->classmap.output;
+ }
+
+ if (class < 0 || class >= router->maplen) {
+ pa_log_debug ("Cannot assign class to routing group '%s': "
+ "id %d out of range (0 - %d)",
+ name, class, router->maplen);
+ return false;
+ }
+
+ classname = agl_node_type_str (class); /* "Player", "Radio"... */
+ direction = agl_node_direction_str (type); /* "input", "output" */
+
+ rtg = pa_hashmap_get (rtable, name);
+ if (!rtg) {
+ pa_log_debug ("Cannot assign class to routing group '%s': "
+ "router group not found", name);
+ return false;
+ }
+
+ zonemap = classmap[zone];
+ if (!zonemap) { /* THIS LOOKS LIKE A HACK TO IGNORE THE ERROR... */
+ zonemap = pa_xnew0 (agl_rtgroup *, router->maplen);
+ classmap[zone] = zonemap;
+ }
+
+ zonemap[class] = rtg;
+
+ /* try to get zone name for logging, if fails, only print id number */
+ rzone = agl_zoneset_get_zone_by_index (u, zone);
+ if (rzone) {
+ pa_log_debug ("class '%s'@'%s' assigned to routing group '%s'",
+ classname, rzone->name, name);
+ } else {
+ pa_log_debug ("class '%s'@zone%d assigned to routing group '%s'",
+ classname, zone, name);
+ }
+
+ return true;
+}
+
+void agl_router_assign_class_priority (struct userdata *u, agl_node_type class, int priority)
+{
+ agl_router *router;
+ int *priormap;
+
+ pa_assert (u);
+ pa_assert_se (router = u->router);
+ pa_assert_se (priormap = router->priormap);
+
+ if (class > 0 && class < router->maplen) {
+ pa_log_debug ("assigning priority %d to class '%s'",
+ priority, agl_node_type_str (class));
+ priormap[class] = priority;
+ }
+}
+
void agl_router_register_node (struct userdata *u, agl_node *node)
{
pa_assert (u);
diff --git a/router.h b/router.h
index d3096ac..498c215 100644
--- a/router.h
+++ b/router.h
@@ -75,6 +75,11 @@ bool agl_router_phone_accept (struct userdata *, agl_rtgroup *, agl_node *);
int agl_router_default_compare (struct userdata *, agl_rtgroup *, agl_node *, agl_node *);
int agl_router_phone_compare (struct userdata *, agl_rtgroup *, agl_node *, agl_node *);
+agl_rtgroup *agl_router_create_rtgroup (struct userdata *, agl_direction, const char *, agl_rtgroup_accept_t, agl_rtgroup_compare_t);
+void agl_router_destroy_rtgroup (struct userdata *, agl_direction, const char *);
+bool agl_router_assign_class_to_rtgroup (struct userdata *, agl_node_type, uint32_t, agl_direction, const char *);
+void agl_router_assign_class_priority (struct userdata *, agl_node_type, int);
+
void agl_router_register_node (struct userdata *, agl_node *);
void agl_router_unregister_node (struct userdata *, agl_node *);
agl_node *agl_router_make_prerouting (struct userdata *, agl_node *);
diff --git a/zone.c b/zone.c
index 3a20ab9..5b1cd07 100644
--- a/zone.c
+++ b/zone.c
@@ -56,3 +56,56 @@ void agl_zoneset_done (struct userdata *u)
free (zs);
}
}
+
+int agl_zoneset_add_zone (struct userdata *u, const char *name, uint32_t index)
+{
+ agl_zoneset *zs;
+ agl_zone *zone;
+
+ pa_assert (u);
+ pa_assert (name);
+ pa_assert (index < AGL_ZONE_MAX);
+ pa_assert_se (zs = u->zoneset);
+
+ zone = pa_xnew (agl_zone, 1);
+ zone->name = pa_xstrdup (name);
+ zone->index = index;
+
+ pa_hashmap_put (zs->zones.hash, (void *)zone->name, zone);
+
+ zs->zones.index[index] = zone;
+
+ return 0;
+}
+
+agl_zone *agl_zoneset_get_zone_by_name (struct userdata *u, const char *name)
+{
+ agl_zoneset *zs;
+ agl_zone *zone;
+
+ pa_assert (u);
+ pa_assert_se (zs = u->zoneset);
+
+ if (name && zs->zones.hash)
+ zone = pa_hashmap_get (zs->zones.hash, name);
+ else
+ zone = NULL;
+
+ return zone;
+}
+
+agl_zone *agl_zoneset_get_zone_by_index (struct userdata *u, uint32_t index)
+{
+ agl_zoneset *zs;
+ agl_zone *zone;
+
+ pa_assert (u);
+ pa_assert_se (zs = u->zoneset);
+
+ if (index < AGL_ZONE_MAX)
+ zone = zs->zones.index[index];
+ else
+ zone = NULL;
+
+ return zone;
+}
diff --git a/zone.h b/zone.h
index c64b879..293d008 100644
--- a/zone.h
+++ b/zone.h
@@ -34,4 +34,8 @@ struct agl_zone {
agl_zoneset *agl_zoneset_init (struct userdata *);
void agl_zoneset_done (struct userdata *);
+int agl_zoneset_add_zone (struct userdata *, const char *, uint32_t);
+agl_zone *agl_zoneset_get_zone_by_name (struct userdata *, const char *);
+agl_zone *agl_zoneset_get_zone_by_index (struct userdata *, uint32_t);
+
#endif