diff options
-rw-r--r-- | config.c | 19 | ||||
-rw-r--r-- | node.c | 31 | ||||
-rw-r--r-- | node.h | 3 | ||||
-rw-r--r-- | router.c | 137 | ||||
-rw-r--r-- | router.h | 5 | ||||
-rw-r--r-- | zone.c | 53 | ||||
-rw-r--r-- | zone.h | 4 |
7 files changed, 252 insertions, 0 deletions
@@ -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; } @@ -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; @@ -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 *); @@ -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); @@ -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 *); @@ -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; +} @@ -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 |