2 * module-agl-audio -- PulseAudio module for providing audio routing support
3 * (forked from "module-murphy-ivi" - https://github.com/otcshare )
4 * Copyright (c) 2012, Intel Corporation.
5 * Copyright (c) 2016, IoT.bzh
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU Lesser General Public License,
9 * version 2.1, as published by the Free Software Foundation.
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE.
14 * See the GNU Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public License
17 * along with this program; if not, write to the
18 * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
25 #include <pulsecore/idxset.h>
26 #include <pulsecore/core-util.h>
27 #include <pulsecore/pulsecore-config.h>
29 agl_nodeset *agl_nodeset_init (struct userdata *u)
35 ns = pa_xnew0 (agl_nodeset, 1);
36 ns->nodes = pa_idxset_new (pa_idxset_trivial_hash_func,
37 pa_idxset_trivial_compare_func);
38 ns->roles = pa_hashmap_new (pa_idxset_string_hash_func,
39 pa_idxset_string_compare_func);
40 ns->binaries = pa_hashmap_new (pa_idxset_string_hash_func,
41 pa_idxset_string_compare_func);
45 void agl_nodeset_done(struct userdata *u)
48 agl_nodeset_map *role, *binary;
52 if (u && (ns = u->nodeset)) {
53 pa_idxset_free (ns->nodes, NULL);
55 PA_HASHMAP_FOREACH(role, ns->roles, state) {
56 pa_xfree ((void *)role->name);
57 pa_xfree ((void *)role->resdef);
59 pa_hashmap_free (ns->roles);
61 PA_HASHMAP_FOREACH(binary, ns->binaries, state) {
62 pa_xfree ((void *)binary->name);
63 pa_xfree ((void *)binary->resdef);
65 pa_hashmap_free (ns->binaries);
67 for (i = 0; i < APCLASS_DIM; i++)
68 pa_xfree((void *)ns->class_name[i]);
74 int agl_nodeset_add_role (struct userdata *u, const char *role, agl_node_type type, agl_nodeset_resdef *resdef)
80 pa_assert_se (ns = u->nodeset);
82 map = pa_xnew0 (agl_nodeset_map, 1);
83 map->name = pa_xstrdup (role);
85 map->role = pa_xstrdup (role);
88 map->resdef = pa_xnew (agl_nodeset_resdef, 1);
89 memcpy (map->resdef, resdef, sizeof(agl_nodeset_resdef));
92 return pa_hashmap_put (ns->roles, (void *)map->name, map);
95 agl_node *agl_node_create (struct userdata *u, agl_node *data)
101 pa_assert_se (ns = u->nodeset);
103 node = pa_xnew0 (agl_node, 1);
105 pa_idxset_put (ns->nodes, node, &node->index);
108 node->key = pa_xstrdup (data->key);
109 node->direction = data->direction;
110 node->implement = data->implement;
111 node->channels = data->channels;
112 node->location = data->location;
113 node->privacy = data->privacy;
114 node->type = data->type;
115 node->zone = pa_xstrdup (data->zone);
116 node->visible = data->visible;
117 node->available = data->available;
118 node->amname = pa_xstrdup (data->amname ? data->amname : data->paname);
119 node->amdescr = pa_xstrdup(data->amdescr ? data->amdescr : "");
120 node->amid = data->amid;
121 node->paname = pa_xstrdup (data->paname);
122 node->stamp = data->stamp;
123 node->rset.id = data->rset.id ? pa_xstrdup(data->rset.id) : NULL;
124 node->rset.grant = data->rset.grant;
126 if (node->implement == agl_device) {
127 node->pacard.index = data->pacard.index;
128 if (data->pacard.profile)
129 node->pacard.profile = pa_xstrdup (data->pacard.profile);
131 node->paport = data->paport;
138 void agl_node_destroy (struct userdata *u, agl_node *node)
144 pa_assert_se (ns = u->nodeset);
146 pa_idxset_remove_by_index (ns->nodes, node->index);
152 agl_node_type agl_node_type_from_str (const char *str)
158 if (pa_streq (str, "agl_radio"))
160 else if (pa_streq (str, "agl_music"))
162 else if (pa_streq (str, "agl_navigator"))
163 type = agl_navigator;
164 else if (pa_streq (str, "agl_game"))
166 else if (pa_streq (str, "agl_browser"))
168 else if (pa_streq (str, "agl_camera"))
170 else if (pa_streq (str, "agl_phone"))
172 else if (pa_streq (str, "agl_alert"))
174 else if (pa_streq (str, "agl_event"))
176 else if (pa_streq (str, "agl_system"))
179 type = agl_node_type_unknown;
184 const char *agl_node_type_str (agl_node_type type)
187 case agl_node_type_unknown: return "Unknown";
188 case agl_radio: return "Radio";
189 case agl_player: return "Player";
190 case agl_navigator: return "Navigator";
191 case agl_game: return "Game";
192 case agl_browser: return "Browser";
193 case agl_camera: return "Camera";
194 case agl_phone: return "Phone";
195 case agl_alert: return "Alert";
196 case agl_event: return "Event";
197 case agl_system: return "System";
198 default: return "default";
202 const char *agl_node_direction_str (agl_direction direction)
205 case agl_direction_unknown: return "unknown";
206 case agl_input: return "input";
207 case agl_output: return "output";
208 default: return "< ??? >";
212 agl_node *agl_node_get_from_data (struct userdata *u, agl_direction type, void *data)
214 pa_sink_input_new_data *sinp_data;
215 pa_source_output_new_data *sout_data;
216 agl_nodeset *nodeset;
222 pa_assert (nodeset = u->nodeset);
224 pa_assert (type == agl_input || type == agl_output);
226 /* input (= sink_input) */
227 if (type == agl_input) {
228 sinp_data = (pa_sink_input_new_data *) data;
229 PA_IDXSET_FOREACH(node, nodeset->nodes, index) {
230 if (node->client == sinp_data->client)
233 /* output (= source_output) TODO */
240 agl_node *agl_node_get_from_client (struct userdata *u, pa_client *client)
242 agl_nodeset *nodeset;
248 pa_assert (nodeset = u->nodeset);
250 PA_IDXSET_FOREACH(node, nodeset->nodes, index) {
251 if (node->client == client)
258 bool agl_node_has_highest_priority (struct userdata *u, agl_node *node)
260 agl_nodeset *nodeset;
267 pa_assert (nodeset = u->nodeset);
269 priority = agl_router_get_node_priority (u, node);
271 PA_IDXSET_FOREACH(n, nodeset->nodes, index) {
272 if ((n != node) && (agl_router_get_node_priority (u, n) >= priority))