#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;
typedef struct {
mir_node_type class;
+ uint32_t zone;
mir_direction type;
const char *rtgroup;
} classmap_def;
+static zone_def zones[] = {
+ "driver",
+ "passanger1",
+ "passanger2",
+ "passanger3",
+ "passanger4",
+ NULL
+};
+
static rtgroup_def rtgroups[] = {
{mir_input,
"phone",
};
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[] = {
static pa_bool_t use_default_configuration(struct userdata *u)
{
+ zone_def *z;
rtgroup_def *r;
classmap_def *c;
typemap_def *t;
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);
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
}
node_type = node.event,
priority = 6,
route = {
- output = routing_group.default_output
+ output = { driver = routing_group.default_driver_output }
},
roles = { event = no_resource }
}
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 }
}
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 }
}
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"} }
}
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"} }
}
node_type = node.radio,
priority = 1,
route = {
- output = routing_group.default_output
+ output = { driver = routing_group.default_driver_output }
},
roles = { radio = {1, "mandatory", "exclusive"} },
}
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"},
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"} }
}
#include <pulsecore/module.h>
#include "router.h"
+#include "zone.h"
#include "node.h"
#include "switch.h"
#include "constrain.h"
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,
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);
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) {
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);
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));
"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;
}
{
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;
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));
#include <sys/types.h>
+#include <murphy/resource/data-types.h>
+
#include "userdata.h"
#include "list.h"
} 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 {
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 *);
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);
pa_nodeset_resdef *resdef;
map_t *r, *b;
size_t i;
+ const char *n;
pa_bool_t ir, or;
MRP_LUA_ENTER;
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;