2 * module-murphy-ivi -- PulseAudio module for providing audio routing support
3 * Copyright (c) 2012, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU Lesser General Public License,
7 * version 2.1, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
22 #include <pulsecore/pulsecore-config.h>
24 #include <pulsecore/hashmap.h>
25 #include <pulsecore/idxset.h>
26 #include <pulsecore/strbuf.h>
32 #include "constrain.h"
33 #include "scripting.h"
36 #define APCLASS_DIM (mir_application_class_end - mir_application_class_begin)
42 const char *class_name[APCLASS_DIM];
46 static void free_map_cb(void *);
47 static int print_map(pa_hashmap *, const char *, char *, int);
49 pa_nodeset *pa_nodeset_init(struct userdata *u)
55 ns = pa_xnew0(pa_nodeset, 1);
56 ns->nodes = pa_idxset_new(pa_idxset_trivial_hash_func,
57 pa_idxset_trivial_compare_func);
58 ns->roles = pa_hashmap_new(pa_idxset_string_hash_func,
59 pa_idxset_string_compare_func);
60 ns->binaries = pa_hashmap_new(pa_idxset_string_hash_func,
61 pa_idxset_string_compare_func);
65 void pa_nodeset_done(struct userdata *u)
70 if (u && (ns = u->nodeset)) {
71 pa_idxset_free(ns->nodes, NULL);
72 pa_hashmap_free(ns->roles, free_map_cb);
73 pa_hashmap_free(ns->binaries, free_map_cb);
75 for (i = 0; i < APCLASS_DIM; i++)
76 pa_xfree((void *)ns->class_name[i]);
82 int pa_nodeset_add_class(struct userdata *u, mir_node_type t,const char *clnam)
87 pa_assert(t >= mir_application_class_begin &&
88 t < mir_application_class_end);
90 pa_assert_se((ns = u->nodeset));
92 if (!ns->class_name[t]) {
93 ns->class_name[t] = pa_xstrdup(clnam);
100 void pa_nodeset_delete_class(struct userdata *u, mir_node_type t)
105 pa_assert(t >= mir_application_class_begin &&
106 t < mir_application_class_end);
107 pa_assert_se((ns = u->nodeset));
109 pa_xfree((void *)ns->class_name[t]);
111 ns->class_name[t] = NULL;
114 const char *pa_nodeset_get_class(struct userdata *u, mir_node_type t)
119 pa_assert_se((ns = u->nodeset));
121 if (t >= mir_application_class_begin && t < mir_application_class_end)
122 return ns->class_name[t];
127 int pa_nodeset_add_role(struct userdata *u,
130 pa_nodeset_resdef *resdef)
137 pa_assert(type >= mir_application_class_begin &&
138 type < mir_application_class_end);
139 pa_assert_se((ns = u->nodeset));
141 map = pa_xnew0(pa_nodeset_map, 1);
142 map->name = pa_xstrdup(role);
146 map->resdef = pa_xnew(pa_nodeset_resdef, 1);
147 memcpy(map->resdef, resdef, sizeof(pa_nodeset_resdef));
150 return pa_hashmap_put(ns->roles, map->name, map);
153 void pa_nodeset_delete_role(struct userdata *u, const char *role)
160 pa_assert_se((ns = u->nodeset));
162 if ((map = pa_hashmap_remove(ns->roles, role))) {
163 pa_xfree((void *)map->name);
164 pa_xfree((void *)map->resdef);
168 pa_nodeset_map *pa_nodeset_get_map_by_role(struct userdata *u,
175 pa_assert_se((ns = u->nodeset));
177 if (role && ns->roles)
178 map = pa_hashmap_get(ns->roles, role);
186 int pa_nodeset_add_binary(struct userdata *u,
189 pa_nodeset_resdef *resdef)
196 pa_assert(type >= mir_application_class_begin &&
197 type < mir_application_class_end);
198 pa_assert_se((ns = u->nodeset));
200 map = pa_xnew0(pa_nodeset_map, 1);
201 map->name = pa_xstrdup(bin);
205 map->resdef = pa_xnew(pa_nodeset_resdef, 1);
206 memcpy(map->resdef, resdef, sizeof(pa_nodeset_resdef));
209 return pa_hashmap_put(ns->binaries, map->name, map);
212 void pa_nodeset_delete_binary(struct userdata *u, const char *bin)
219 pa_assert_se((ns = u->nodeset));
221 if ((map = pa_hashmap_remove(ns->binaries, bin))) {
222 pa_xfree((void *)map->name);
223 pa_xfree((void *)map->resdef);
227 pa_nodeset_map *pa_nodeset_get_map_by_binary(struct userdata *u,
234 pa_assert_se((ns = u->nodeset));
237 map = pa_hashmap_get(ns->binaries, bin);
245 int pa_nodeset_print_maps(struct userdata *u, char *buf, int len)
254 pa_assert_se((ns = u->nodeset));
258 p += print_map(ns->roles, "roles", p, e-p);
259 p += print_map(ns->binaries, "binaries", p, e-p);
264 mir_node *pa_nodeset_iterate_nodes(struct userdata *u, uint32_t *pidx)
272 pa_assert_se((ns = u->nodeset));
273 pa_assert_se((idxset = ns->nodes));
275 if (*pidx == PA_IDXSET_INVALID)
276 node = pa_idxset_first(idxset, pidx);
278 node = pa_idxset_next(idxset, pidx);
283 mir_node *mir_node_create(struct userdata *u, mir_node *data)
290 pa_assert_se((ns = u->nodeset));
291 pa_assert(data->key);
292 pa_assert(data->paname);
294 node = pa_xnew0(mir_node, 1);
296 pa_idxset_put(ns->nodes, node, &node->index);
298 node->key = pa_xstrdup(data->key);
299 node->direction = data->direction;
300 node->implement = data->implement;
301 node->channels = data->channels;
302 node->location = data->location;
303 node->privacy = data->privacy;
304 node->type = data->type;
305 node->zone = pa_xstrdup(data->zone);
306 node->visible = data->visible;
307 node->available = data->available;
308 node->amname = pa_xstrdup(data->amname ? data->amname : data->paname);
309 node->amdescr = pa_xstrdup(data->amdescr ? data->amdescr : "");
310 node->amid = data->amid;
311 node->paname = pa_xstrdup(data->paname);
312 node->paidx = data->paidx;
313 node->mux = data->mux;
314 node->loop = data->loop;
315 node->stamp = data->stamp;
316 node->rsetid = data->rsetid ? pa_xstrdup(data->rsetid) : NULL;
317 node->scripting = pa_scripting_node_create(u, node);
318 MIR_DLIST_INIT(node->rtentries);
319 MIR_DLIST_INIT(node->rtprilist);
320 MIR_DLIST_INIT(node->constrains);
322 if (node->implement == mir_device) {
323 node->pacard.index = data->pacard.index;
324 if (data->pacard.profile)
325 node->pacard.profile = pa_xstrdup(data->pacard.profile);
327 node->paport = pa_xstrdup(data->paport);
330 mir_router_register_node(u, node);
335 void mir_node_destroy(struct userdata *u, mir_node *node)
340 pa_assert_se((ns = u->nodeset));
343 if (node->implement == mir_stream) {
345 pa_murphyif_destroy_resource_set(u, node);
347 pa_murphyif_delete_node(u, node);
350 mir_router_unregister_node(u, node);
351 pa_scripting_node_destroy(u, node);
353 pa_idxset_remove_by_index(ns->nodes, node->index);
356 pa_xfree(node->zone);
357 pa_xfree(node->amname);
358 pa_xfree(node->amdescr);
359 pa_xfree(node->paname);
360 pa_xfree(node->pacard.profile);
361 pa_xfree(node->paport);
362 pa_xfree(node->rsetid);
368 mir_node *mir_node_find_by_index(struct userdata *u, uint32_t nodidx)
374 pa_assert_se((ns = u->nodeset));
376 node = pa_idxset_get_by_index(ns->nodes, nodidx);
382 int mir_node_print(mir_node *node, char *buf, int len)
393 pa_multiplex_print(node->mux, mux, sizeof(mux));
394 pa_loopback_print(node->loop, loop, sizeof(loop));
395 mir_constrain_print(node, constr, sizeof(constr));
399 #define PRINT(f,v) if (p < e) p += snprintf(p, e-p, f "\n", v)
401 PRINT(" index : %u" , node->index);
402 PRINT(" key : '%s'", node->key ? node->key : "");
403 PRINT(" direction : %s" , mir_direction_str(node->direction));
404 PRINT(" implement : %s" , mir_implement_str(node->implement));
405 PRINT(" channels : %u" , node->channels);
406 PRINT(" location : %s" , mir_location_str(node->location));
407 PRINT(" privacy : %s" , mir_privacy_str(node->privacy));
408 PRINT(" type : %s" , mir_node_type_str(node->type));
409 PRINT(" zone : '%s'", node->zone ? node->zone : "");
410 PRINT(" visible : %s" , node->visible ? "yes" : "no");
411 PRINT(" available : %s" , node->available ? "yes" : "no");
412 PRINT(" ignore : %s" , node->ignore ? "yes" : "no");
413 PRINT(" localrset : %s" , node->localrset ? "yes" : "no");
414 PRINT(" amname : '%s'", node->amname ? node->amname : "");
415 PRINT(" amdescr : '%s'", node->amdescr ? node->amdescr : "");
416 PRINT(" amid : %u" , node->amid);
417 PRINT(" paname : '%s'", node->paname ? node->paname : "");
418 PRINT(" paidx : %u" , node->paidx);
419 PRINT(" pacard.index : %u" , node->pacard.index);
420 PRINT(" pacard.profile: '%s'", node->pacard.profile ?
421 node->pacard.profile : "");
422 PRINT(" paport : '%s'", node->paport ? node->paport : "");
423 PRINT(" mux : %s" , mux);
424 PRINT(" loop : %s" , loop);
425 PRINT(" constrain : %s" , constr);
426 PRINT(" rsetid : '%s'", node->rsetid ? node->rsetid : "");
427 PRINT(" stamp : %u" , node->stamp);
434 const char *mir_direction_str(mir_direction direction)
437 case mir_direction_unknown: return "unknown";
438 case mir_input: return "input";
439 case mir_output: return "output";
440 default: return "< ??? >";
444 const char *mir_implement_str(mir_implement implement)
447 case mir_implementation_unknown: return "unknown";
448 case mir_device: return "device";
449 case mir_stream: return "stream";
450 default: return "< ??? >";
454 const char *mir_location_str(mir_location location)
457 case mir_location_unknown: return "unknown";
458 case mir_internal: return "internal";
459 case mir_external: return "external";
460 default: return "< ??? >";
465 const char *mir_node_type_str(mir_node_type type)
468 case mir_node_type_unknown: return "Unknown";
469 case mir_radio: return "Radio";
470 case mir_player: return "Player";
471 case mir_navigator: return "Navigator";
472 case mir_game: return "Game";
473 case mir_browser: return "Browser";
474 case mir_camera: return "Camera";
475 case mir_phone: return "Phone";
476 case mir_alert: return "Alert";
477 case mir_event: return "Event";
478 case mir_system: return "System";
479 case mir_speakers: return "Speakers";
480 case mir_microphone: return "Microphone";
481 case mir_jack: return "Line";
482 case mir_spdif: return "SPDIF";
483 case mir_hdmi: return "HDMI";
484 case mir_wired_headset: return "Wired Headset";
485 case mir_wired_headphone: return "Wired Headphone";
486 case mir_usb_headset: return "USB Headset";
487 case mir_bluetooth_sco: return "Bluetooth Mono Handsfree";
488 case mir_bluetooth_carkit: return "Car Kit";
489 case mir_bluetooth_a2dp: return "Bluetooth Stereo Headphone";
490 case mir_bluetooth_source: return "Bluetooth Source";
491 case mir_bluetooth_sink: return "Bluetooth Sink";
492 default: return "<user defined>";
497 const char *mir_privacy_str(mir_privacy privacy)
500 case mir_privacy_unknown: return "<unknown>";
501 case mir_public: return "public";
502 case mir_private: return "private";
503 default: return "< ??? >";
508 static void free_map_cb(void *void_map)
510 pa_nodeset_map *map = (pa_nodeset_map *)void_map;
512 pa_xfree((void *)map->name);
513 pa_xfree((void *)map->resdef);
518 static int print_map(pa_hashmap *map, const char *name, char *buf, int len)
520 #define PRINT(fmt,args...) \
521 do { if (p < e) p += snprintf(p, e-p, fmt "\n", args); } while (0)
524 pa_nodeset_resdef *r;
531 if (buf && len > 0) {
532 PRINT("%s mappings:", name);
534 PA_HASHMAP_FOREACH(m, map, state) {
535 type = mir_node_type_str(m->type);
537 if (!(r = m->resdef))
538 PRINT(" %-15s => %-10s", m->name, type);
540 PRINT(" %-15s => %-10s resource: priority %u, flags rset "
541 "0x%x, audio 0x%x", m->name, type, r->priority,
542 r->flags.rset, r->flags.audio);
555 * indent-tabs-mode: nil