class + zone based mapping for routing groups 89/8989/1
authorJanos Kovacs <jankovac503@gmail.com>
Fri, 16 Aug 2013 16:40:37 +0000 (19:40 +0300)
committerJaska Uimonen <jaska.uimonen@helsinki.fi>
Tue, 20 Aug 2013 08:20:03 +0000 (11:20 +0300)
murphy/murphy-config.c
murphy/murphy-ivi.lua
murphy/router.c
murphy/router.h
murphy/scripting.c

index b084d8f..5184ac0 100644 (file)
 #include <pulsecore/pulsecore-config.h>
 
 #include "murphy-config.h"
+#include "zone.h"
 #include "node.h"
 #include "router.h"
 #include "volume.h"
 #include "scripting.h"
 
 typedef struct {
+    const char *name;
+} zone_def;
+
+typedef struct {
     mir_direction          type;
     const char            *name;
     mir_rtgroup_accept_t   accept;
@@ -39,6 +44,7 @@ typedef struct {
 
 typedef struct {
     mir_node_type  class;
+    uint32_t       zone;
     mir_direction  type;
     const char    *rtgroup;
 } classmap_def;
@@ -55,6 +61,15 @@ typedef struct {
 
 
 
+static zone_def zones[] = {
+    "driver",
+    "passanger1",
+    "passanger2",
+    "passanger3",
+    "passanger4",
+    NULL
+};
+
 static rtgroup_def  rtgroups[] = {
     {mir_input,
      "phone",
@@ -78,16 +93,15 @@ static rtgroup_def  rtgroups[] = {
 };
 
 static classmap_def classmap[] = {
-    {mir_phone    , mir_input , "phone"  },
-
-    {mir_radio    , mir_output, "default"},
-    {mir_player   , mir_output, "default"},
-    {mir_navigator, mir_output, "default"},
-    {mir_game     , mir_output, "default"},
-    {mir_browser  , mir_output, "default"},
-    {mir_phone    , mir_output, "phone"  },
-    {mir_event    , mir_output, "default"},
-    {mir_node_type_unknown, mir_direction_unknown, NULL}
+    {mir_phone    , 0, mir_input , "phone"  },
+    {mir_radio    , 0, mir_output, "default"},
+    {mir_player   , 0, mir_output, "default"},
+    {mir_navigator, 0, mir_output, "default"},
+    {mir_game     , 0, mir_output, "default"},
+    {mir_browser  , 0, mir_output, "default"},
+    {mir_phone    , 0, mir_output, "phone"  },
+    {mir_event    , 0, mir_output, "default"},
+    {mir_node_type_unknown, 0, mir_direction_unknown, NULL}
 };
 
 static typemap_def rolemap[] = {
@@ -193,6 +207,7 @@ pa_bool_t pa_mir_config_parse_file(struct userdata *u, const char *path)
 
 static pa_bool_t use_default_configuration(struct userdata *u)
 {
+    zone_def     *z;
     rtgroup_def  *r;
     classmap_def *c;
     typemap_def  *t;
@@ -200,11 +215,16 @@ static pa_bool_t use_default_configuration(struct userdata *u)
 
     pa_assert(u);
 
+    for (z = zones;  z->name;  z++)
+        pa_zoneset_add_zone(u, z->name, z - zones);
+
     for (r = rtgroups;  r->name;   r++)
         mir_router_create_rtgroup(u, r->type, r->name, r->accept, r->compare);
 
-    for (c = classmap;  c->rtgroup;  c++)
-        mir_router_assign_class_to_rtgroup(u, c->class, c->type, c->rtgroup);
+    for (c = classmap;  c->rtgroup;  c++) {
+        mir_router_assign_class_to_rtgroup(u, c->class, c->zone,
+                                           c->type, c->rtgroup);
+    }
 
     for (t = rolemap; t->id; t++)
         pa_nodeset_add_role(u, t->id, t->type, NULL);
index 39cef79..acd0752 100644 (file)
@@ -5,9 +5,20 @@ zone { name = "passanger3" }
 zone { name = "passanger4" }
 
 routing_group {
-    name = "default",
+    name = "default_driver",
     node_type = node.output,
-    accept = builtin.method.accept_default,
+    accept = function(self, n)
+        return (n.type ~= node.bluetooth_carkit and n.type ~= node.hdmi)
+    end,
+    compare = builtin.method.compare_default
+}
+
+routing_group {
+    name = "default_passanger1",
+    node_type = node.output,
+    accept = function(self, n)
+        return (n.type == node.hdmi or n.name == 'Silent')
+    end,
     compare = builtin.method.compare_default
 }
 
@@ -29,7 +40,7 @@ application_class {
     node_type = node.event,
     priority = 6,
     route = {
-        output = routing_group.default_output
+        output = { driver = routing_group.default_driver_output }
     },
     roles = { event = no_resource }
 }
@@ -39,8 +50,8 @@ application_class {
     node_type = node.phone,
     priority = 5,
     route = {
-        input = routing_group.phone_input,
-        output = routing_group.phone_output
+        input  = { driver = routing_group.phone_input },
+        output = {driver = routing_group.phone_output }
     },
     roles = { phone = no_resource, carkit = no_resource }
 }
@@ -49,7 +60,7 @@ application_class {
     node_type = node.alert,
     priority = 4,
     route = {
-        output = routing_group.default_output
+        output = { driver = routing_group.default_driver_output },
     },
     roles = { ringtone = no_resource, alarm = no_resource }
 }
@@ -59,7 +70,8 @@ application_class {
     node_type = node.navigator,
     priority = 3,
     route = {
-        output = routing_group.default_output
+        output = { driver = routing_group.default_driver_output,
+                  passanger1 = routing_group.default_passanger1_output }
     },
     roles = { navigator = {0, "autorelease", "mandatory", "shared"} }
 }
@@ -69,7 +81,8 @@ application_class {
     node_type = node.game,
     priority = 2,
     route = {
-        output = routing_group.default_output
+        output = { driver = routing_group.default_driver_output,
+                  passanger1 = routing_group.default_passanger1_output }
     },
     roles = { game = {0, "mandatory", "exclusive"} }
 }
@@ -79,7 +92,7 @@ application_class {
     node_type = node.radio,
     priority = 1,
     route = {
-        output = routing_group.default_output
+        output = { driver = routing_group.default_driver_output }
     },
     roles = { radio = {1, "mandatory", "exclusive"} },
 }
@@ -89,7 +102,8 @@ application_class {
     node_type = node.player,
     priority = 1,
     route = {
-        output = routing_group.default_output
+        output = { driver = routing_group.default_driver_output,
+                  passanger1 = routing_group.default_passanger1_output }
     },
     roles = { music   = {0, "mandatory", "exclusive"},
               video   = {0, "mandatory", "exclusive"},
@@ -102,7 +116,8 @@ application_class {
     node_type = node.browser,
     priority = 1,
     route = {
-        output = routing_group.default_output
+        output = { driver = routing_group.default_driver_output,
+                  passanger1 = routing_group.default_passanger1_output }
     },
     roles = { browser = {0, "mandatory", "shared"} }
 }
index 6d1aa1f..9e3959e 100644 (file)
@@ -28,6 +28,7 @@
 #include <pulsecore/module.h>
 
 #include "router.h"
+#include "zone.h"
 #include "node.h"
 #include "switch.h"
 #include "constrain.h"
@@ -70,7 +71,7 @@ static void pa_hashmap_rtgroup_free(void *rtg, void *u)
 
 pa_router *pa_router_init(struct userdata *u)
 {
-    size_t     num_classes = mir_application_class_end;
+    size_t num_classes = mir_application_class_end;
     pa_router *router = pa_xnew0(pa_router, 1);
     
     router->rtgroups.input  = pa_hashmap_new(pa_idxset_string_hash_func,
@@ -80,9 +81,6 @@ pa_router *pa_router_init(struct userdata *u)
 
     router->maplen = num_classes;
 
-    router->classmap.input  = pa_xnew0(mir_rtgroup *, num_classes);
-    router->classmap.output = pa_xnew0(mir_rtgroup *, num_classes);
-
     router->priormap = pa_xnew0(int, num_classes);
 
     MIR_DLIST_INIT(router->nodlist);
@@ -98,6 +96,8 @@ void pa_router_done(struct userdata *u)
     mir_node       *e,*n;
     void           *state;
     mir_rtgroup    *rtg;
+    mir_rtgroup   **map;
+    int             i;
 
     if (u && (router = u->router)) {
         MIR_DLIST_FOR_EACH_SAFE(mir_node, rtprilist, e,n, &router->nodlist) {
@@ -120,8 +120,13 @@ void pa_router_done(struct userdata *u)
         pa_hashmap_free(router->rtgroups.input, NULL);
         pa_hashmap_free(router->rtgroups.output, NULL);
 
-        pa_xfree(router->classmap.input);
-        pa_xfree(router->classmap.output);
+        for (i = 0;  i < MRP_ZONE_MAX;  i++) {
+            if ((map = router->classmap.input[i]))
+                pa_xfree(map);
+
+            if ((map = router->classmap.output[i]))
+                pa_xfree(map);
+        }
 
         pa_xfree(router->priormap);
         pa_xfree(router);
@@ -224,17 +229,21 @@ void mir_router_destroy_rtgroup(struct userdata *u,
 
 pa_bool_t mir_router_assign_class_to_rtgroup(struct userdata *u,
                                              mir_node_type    class,
+                                             uint32_t         zone,
                                              mir_direction    type,
                                              const char      *rtgrpnam)
 {
     pa_router *router;
     pa_hashmap *rtable;
-    mir_rtgroup **classmap;
+    mir_rtgroup ***classmap;
+    mir_rtgroup **zonemap;
     mir_rtgroup *rtg;
     const char *clnam;
     const char *direction;
+    mir_zone *z;
 
     pa_assert(u);
+    pa_assert(zone < MRP_ZONE_MAX);
     pa_assert(type == mir_input || type == mir_output);
     pa_assert(rtgrpnam);
     pa_assert_se((router = u->router));
@@ -263,10 +272,21 @@ pa_bool_t mir_router_assign_class_to_rtgroup(struct userdata *u,
                      "router group not found", clnam, direction, rtgrpnam);
     }
 
-    classmap[class] = rtg;
+    if (!(zonemap = classmap[zone])) {
+        zonemap = pa_xnew0(mir_rtgroup *, router->maplen);
+        classmap[zone] = zonemap;
+    }
 
-    pa_log_debug("class '%s' assigned to %s routing group '%s'",
-                 clnam, direction, rtgrpnam);
+    zonemap[class] = rtg;
+
+    if ((z = pa_zoneset_get_zone_by_index(u, zone))) {
+        pa_log_debug("class '%s'@'%s' assigned to %s routing group '%s'",
+                     clnam, z->name, direction, rtgrpnam);
+    }
+    else {
+        pa_log_debug("class '%s'@zone%u assigned to %s routing group '%s'",
+                     clnam, zone, direction, rtgrpnam);
+    }
 
     return TRUE;
 }
@@ -832,7 +852,9 @@ static mir_node *find_default_route(struct userdata *u,
 {
     pa_router     *router = u->router;
     mir_node_type  class  = pa_classify_guess_application_class(start);
-    mir_rtgroup  **classmap;
+    mir_zone      *zone   = pa_zoneset_get_zone_by_name(u, start->zone);
+    mir_rtgroup ***cmap;
+    mir_rtgroup  **zmap;
     mir_node      *end;
     mir_rtgroup   *rtg;
     mir_rtentry   *rte;
@@ -842,14 +864,20 @@ static mir_node *find_default_route(struct userdata *u,
                      start->amname, class, router->maplen);
         return NULL;
     }
+
+    if (!zone) {
+        pa_log_debug("can't route '%s': zone '%s' is unknown",
+                     start->amname, start->zone);
+        return NULL;
+    }
     
     switch (start->direction) {
-    case mir_input:     classmap = router->classmap.output;     break;
-    case mir_output:    classmap = router->classmap.input;      break;
-    default:            classmap = NULL;                        break;
+    case mir_input:     cmap = router->classmap.output;     break;
+    case mir_output:    cmap = router->classmap.input;      break;
+    default:            cmap = NULL;                        break;
     }
 
-    if (!classmap || !(rtg = classmap[class])) {
+    if (!cmap || !(zmap = cmap[zone->index]) || !(rtg = zmap[class])) {
         pa_log_debug("node '%s' won't be routed beacuse its class '%s' "
                      "is not assigned to any router group",
                      start->amname, mir_node_type_str(class));
index a262865..27a0f65 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <sys/types.h>
 
+#include <murphy/resource/data-types.h>
+
 #include "userdata.h"
 #include "list.h"
 
@@ -36,8 +38,8 @@ typedef struct {
 } pa_rtgroup_hash;
 
 typedef struct {
-    mir_rtgroup **input;
-    mir_rtgroup **output;
+    mir_rtgroup **input[MRP_ZONE_MAX];
+    mir_rtgroup **output[MRP_ZONE_MAX];
 } pa_rtgroup_classmap;
 
 struct pa_router {
@@ -90,7 +92,8 @@ mir_rtgroup *mir_router_create_rtgroup(struct userdata *,
 void mir_router_destroy_rtgroup(struct userdata *, mir_direction,
                                 const char *);
 pa_bool_t mir_router_assign_class_to_rtgroup(struct userdata *, mir_node_type,
-                                             mir_direction,  const char *);
+                                             uint32_t, mir_direction,
+                                             const char *);
 
 void mir_router_register_node(struct userdata *, mir_node *);
 void mir_router_unregister_node(struct userdata *, mir_node *);
index 3b1bbcb..502d0fd 100644 (file)
@@ -1184,8 +1184,7 @@ static int zone_create(lua_State *L)
     if (pa_zoneset_add_zone(u, name, index+1))
         luaL_error(L, "attempt to define zone '%s' multiple times", name);
 
-    zone = (scripting_zone *)mrp_lua_create_object(L, ZONE_CLASS,
-                                                   "definition",0);
+    zone = (scripting_zone *)mrp_lua_create_object(L, ZONE_CLASS, name, 0);
 
     zone->userdata = u;
     zone->name = pa_xstrdup(name);
@@ -1705,6 +1704,7 @@ static int apclass_create(lua_State *L)
     pa_nodeset_resdef *resdef;
     map_t *r, *b;
     size_t i;
+    const char *n;
     pa_bool_t ir, or;
 
     MRP_LUA_ENTER;
@@ -1743,21 +1743,26 @@ static int apclass_create(lua_State *L)
 
     mir_router_assign_class_priority(u, type, priority); 
 
-    /*
-    ir = !route->input  ? TRUE : mir_router_assign_class_to_rtgroup(
-                                                        u, type,
-                                                        mir_input,
-                                                        route->input);
-    or = !route->output ? TRUE : mir_router_assign_class_to_rtgroup(
-                                                        u, type,
-                                                        mir_output,
-                                                        route->output);
-    */
+    ir = or = TRUE;
+
+    if (route->input) {
+        for (i = 0;  i < MRP_ZONE_MAX;  i++) {
+            if ((n = route->input[i]))
+                ir &= mir_router_assign_class_to_rtgroup(u,type,i,mir_input,n);
+        }
+    }
+
+    if (route->output) {
+        for (i = 0;  i < MRP_ZONE_MAX;  i++) {
+            if ((n = route->output[i]))
+                or &= mir_router_assign_class_to_rtgroup(u,type,i,mir_output,n);
+        }
+    }
 
     ac = (scripting_apclass *)mrp_lua_create_object(L, APPLICATION_CLASS,
                                                     name, 0);
 
-    if (/* !ir || !or || */ !ac)
+    if (!ir || !or || !ac)
         luaL_error(L, "failed to create application class '%s'", name);
 
     ac->userdata = u;