Map labels to classes, map routing groups to audio adapters
authorManuel Bachmann <manuel.bachmann@iot.bzh>
Wed, 6 Jul 2016 08:16:36 +0000 (10:16 +0200)
committerYannick Gicquel <yannick.gicquel@iot.bzh>
Tue, 11 Oct 2016 15:09:07 +0000 (17:09 +0200)
Change-Id: I563aa146eba8de594900c02b44f19f526a5cdc0e
Signed-off-by: Manuel Bachmann <manuel.bachmann@iot.bzh>
classify.c
config.c
config.h
node.c
router.c
router.h
switch.c
utils.c
utils.h

index c049fad..4d10ce0 100644 (file)
 #include <pulsecore/core-util.h>        /* required for "pa_streq" */
 
 #include "classify.h"
+#include "node.h"
 
 agl_node_type agl_classify_guess_stream_node_type (struct userdata *u,  pa_proplist *pl)
 {
+       agl_nodeset *ns;
+       agl_nodeset_map *map;
        agl_node_type type;
        const char *role;
 
        pa_assert (u);
        pa_assert (pl);
+       pa_assert_se (ns = u->nodeset);
 
        role = pa_proplist_gets (pl, PA_PROP_MEDIA_ROLE);
 
        if (!role)
                type = agl_node_type_unknown;
+
+        /* ask the configuration, see defaults in "config.c" */
+       else if (map = pa_hashmap_get (ns->roles, role))
+               type = map->type;
+        /* configuration did not match, here are some sensible defaults */
        else if (pa_streq (role, "radio"))
                type = agl_radio;
        else if (pa_streq (role, "music"))
index 26d725e..b978296 100644 (file)
--- a/config.c
+++ b/config.c
@@ -22,6 +22,8 @@
 #include "config.h"
 #include "zone.h"
 
+bool use_default_configuration (struct userdata *);
+
 const char *agl_config_file_get_path (const char *dir, const char *file, char *buf, size_t len)
 {
        pa_assert (file);
@@ -48,7 +50,7 @@ bool agl_config_parse_file (struct userdata *u, const char *path)
 
        if (!success) {
                pa_log_info ("applying builtin default configuration");
-               //success = use_default_configuration (u);
+               success = use_default_configuration (u);
        }
 
        return success;
@@ -75,20 +77,21 @@ static zone_def zones[] = {
 
 static rtgroup_def rtgroups[] = {
        { agl_input,
-         "phone",
+         "Phone",
+         "PhoneCard",
          agl_router_phone_accept,
          agl_router_phone_compare
        },
 
-       { 0, NULL, NULL, NULL }
+       { 0, NULL, NULL, NULL, NULL }
 };
 
 static classmap_def classmap[] = {
-       { agl_phone,    0, agl_output, "phone" },
-       { agl_player,   0, agl_output, "default" },
-       { agl_radio,    0, agl_output, "default" },
-       { agl_navigator,0, agl_output, "default" },
-       { agl_event,    0, agl_output, "default" },
+       { agl_phone,    0, agl_input, "Phone" },
+       { agl_player,   0, agl_input, "default" },
+       { agl_radio,    0, agl_input, "default" },
+       { agl_navigator,0, agl_input, "default" },
+       { agl_event,    0, agl_input, "default" },
        { agl_node_type_unknown, 0, agl_direction_unknown, NULL }
 };
 
@@ -124,7 +127,8 @@ bool use_default_configuration (struct userdata *u)
                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);
+               agl_router_create_rtgroup (u, r->type, r->name, r->node_desc,
+                                             r->accept, r->compare);
 
        for (c = classmap; c->rtgroup; c++)
                agl_router_assign_class_to_rtgroup (u, c->class, c->zone,
index 1430824..f39c9fb 100644 (file)
--- a/config.h
+++ b/config.h
@@ -34,6 +34,7 @@ typedef struct {
 typedef struct {
        agl_direction type;             /* agl_input/agl_output */
        const char *name;
+       const char *node_desc;
        agl_rtgroup_accept_t accept;
        agl_rtgroup_compare_t compare;
 } rtgroup_def;
diff --git a/node.c b/node.c
index e2c5007..1876a67 100644 (file)
--- a/node.c
+++ b/node.c
@@ -149,7 +149,7 @@ const char *agl_node_type_str (agl_node_type type)
                case agl_alert:             return "Alert";
                case agl_event:             return "Event";
                case agl_system:            return "System";
-               default:                    return "<user defined>";
+               default:                    return "default";
        }
 }
 
index fa05d4e..e47a3d3 100644 (file)
--- a/router.c
+++ b/router.c
@@ -109,18 +109,19 @@ 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_rtgroup *agl_router_create_rtgroup (struct userdata *u, agl_direction type, const char *name, const char *node_desc, agl_rtgroup_accept_t accept, agl_rtgroup_compare_t compare)
 {
        agl_router *router;
        agl_rtgroup *rtg;
+       agl_nodeset *nodeset;
+       agl_node *node;
        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);
+       pa_assert_se (nodeset = u->nodeset);
 
        if (type == agl_input)
                table = router->rtgroups.input;
@@ -133,6 +134,21 @@ agl_rtgroup *agl_router_create_rtgroup (struct userdata *u, agl_direction type,
        rtg->accept = accept;
        rtg->compare = compare;
        AGL_DLIST_INIT(rtg->entries);
+       /* associate an agl_output node for an agl_input routing group */
+       if (type == agl_input) {
+               node = agl_node_create (u, NULL);
+               node->direction = agl_output;
+               node->implement = agl_device;
+               node->visible = true;
+               node->available = true;
+               node->paname = pa_xstrdup (node_desc);
+                /* add to global nodeset */
+               pa_idxset_put (nodeset->nodes, node, &node->index);
+               rtg->node = node;
+       } else {
+               rtg->node = NULL;
+       }
+       
 
        pa_hashmap_put (table, rtg->name, rtg);
 
@@ -247,10 +263,28 @@ void agl_router_assign_class_priority (struct userdata *u, agl_node_type class,
 
 void agl_router_register_node (struct userdata *u, agl_node *node)
 {
+       agl_router *router;
+       agl_rtgroup *rtg;
+
        pa_assert (u);
        pa_assert (node);
+       pa_assert_se (router = u->router);
 
-       implement_default_route (u, node, NULL, agl_utils_new_stamp ());
+       /* we try to discover node routing group from the configuration, "Phone" for instance,
+        * see defaults in "config.c. Otherwise we just say NULL, a.k.a. default */
+       if (node->direction == agl_input) {
+               rtg = pa_hashmap_get (router->rtgroups.input, agl_node_type_str (node->type));
+               if (rtg)
+                       implement_default_route (u, node, rtg->node, agl_utils_new_stamp ());
+               else
+                       implement_default_route (u, node, NULL, agl_utils_new_stamp ());
+       } else {
+               rtg = pa_hashmap_get (router->rtgroups.output, agl_node_type_str (node->type));
+               if (rtg)
+                       implement_default_route (u, rtg->node, node, agl_utils_new_stamp ());
+               else
+                       implement_default_route (u, NULL, node, agl_utils_new_stamp ());
+       }
 }
 
 void agl_router_unregister_node (struct userdata *u, agl_node *node)
index 498c215..0bf21d5 100644 (file)
--- a/router.h
+++ b/router.h
@@ -32,8 +32,9 @@ typedef bool (*agl_rtgroup_accept_t)(struct userdata *, agl_rtgroup *, agl_node
 typedef int (*agl_rtgroup_compare_t)(struct userdata *, agl_rtgroup *, agl_node *, agl_node *);
 
 struct agl_rtgroup {
-       char *name;      /**< name of the rtgroup */
+       char *name;          /**< name of the rtgroup */
        agl_dlist entries;   /**< listhead of ordered rtentries */
+       agl_node *node;      /**< final node */
        agl_rtgroup_accept_t accept; /**< function pointer, whether to accept a node or not */
        agl_rtgroup_compare_t compare; /**< function pointer, comparision for ordering */
 };
@@ -75,7 +76,7 @@ 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);
+agl_rtgroup *agl_router_create_rtgroup (struct userdata *, agl_direction, const char *, 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);
index 954effd..8111068 100644 (file)
--- a/switch.c
+++ b/switch.c
@@ -103,15 +103,13 @@ bool agl_switch_setup_link (struct userdata *u, agl_node *from, agl_node *to, bo
 
                                /* DEVICE DESTINATION */
                                case agl_device:
-                               /* IF THERE IS NO SOURCE : DEFAULT OUTPUT PREROUTE */
-                               /* if (!from)
-                                       return setup_device_output(u, to) != NULL;
-                               else { */
                                switch (from->implement) {
                                        /* STREAM TO DEVICE : OK */
                                        case agl_stream:
-                                               //if (!setup_default_stream2dev_link (u, from, to))
-                                               //      return false;
+                                               sink = agl_utils_get_alsa_sink (u, to->paname);
+                                               source = agl_utils_get_null_source (u, from->nullsink);
+
+                                               from->loopnode = agl_loopnode_create (u, AGL_LOOPNODE_SINK, from->index, source->index, sink->index);
                                                break;
                                        /* DEVICE TO DEVICE : OK */
                                        case agl_device:
diff --git a/utils.c b/utils.c
index 88425d2..9476c69 100644 (file)
--- a/utils.c
+++ b/utils.c
@@ -196,13 +196,31 @@ pa_sink *agl_utils_get_primary_alsa_sink (struct userdata *u)
        pa_assert_se ((core = u->core));
 
         PA_IDXSET_FOREACH(sink, core->sinks, idx) {
-               if (sink->name && strstr (sink->name, "alsa_output"))
+               if (sink->name && strstr (sink->name, "alsa_output") && strstr (sink->name, "pci"))
                        return sink;
         }
 
        return NULL;
 }
 
+pa_sink *agl_utils_get_alsa_sink (struct userdata *u, const char *name)
+{
+       pa_core *core;
+       pa_sink *sink;
+       int idx;
+
+       pa_assert (u);
+       pa_assert_se ((core = u->core));
+
+        PA_IDXSET_FOREACH(sink, core->sinks, idx) {
+               if (sink->name && strstr (sink->name, "alsa_output")
+                              && strstr (sink->name, name))
+                               return sink;
+        }
+
+       return NULL;
+}
+
 void agl_utils_init_stamp (void)
 {
        stamp = 0;
diff --git a/utils.h b/utils.h
index 611283a..19faeb2 100644 (file)
--- a/utils.h
+++ b/utils.h
@@ -41,6 +41,7 @@ const char *agl_utils_get_source_name (pa_source *);
 const char *agl_utils_get_sink_input_name (pa_sink_input *);
 const char *agl_utils_get_source_output_name (pa_source_output *);
 pa_sink *agl_utils_get_primary_alsa_sink (struct userdata *);
+pa_sink *agl_utils_get_alsa_sink (struct userdata *, const char *);
 void agl_utils_init_stamp (void);
 uint32_t agl_utils_new_stamp (void);
 uint32_t agl_utils_get_stamp (void);