Map labels to classes, map routing groups to audio adapters
[staging/agl-audio-plugin.git] / node.c
1 /*
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
6  *
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.
10  *
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.
15  *
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,
19  * MA 02110-1301 USA.
20  *
21  */
22 #include "node.h"
23
24 #include <pulsecore/idxset.h>
25
26 agl_nodeset *agl_nodeset_init (struct userdata *u)
27 {
28         agl_nodeset *ns;
29
30         pa_assert (u);
31
32         ns = pa_xnew0 (agl_nodeset, 1);
33         ns->nodes = pa_idxset_new (pa_idxset_trivial_hash_func,
34                                    pa_idxset_trivial_compare_func);
35         ns->roles = pa_hashmap_new (pa_idxset_string_hash_func,
36                                     pa_idxset_string_compare_func);
37         ns->binaries = pa_hashmap_new (pa_idxset_string_hash_func,
38                                        pa_idxset_string_compare_func);
39         return ns;
40 }
41
42 void agl_nodeset_done(struct userdata *u)
43 {
44         agl_nodeset *ns;
45         agl_nodeset_map *role, *binary;
46         void *state;
47         int i;
48
49         if (u && (ns = u->nodeset)) {
50                 pa_idxset_free (ns->nodes, NULL);
51
52                 PA_HASHMAP_FOREACH(role, ns->roles, state) {
53                         pa_xfree ((void *)role->name);
54                         pa_xfree ((void *)role->resdef);
55                 }
56                 pa_hashmap_free (ns->roles);
57
58                 PA_HASHMAP_FOREACH(binary, ns->binaries, state) {
59                         pa_xfree ((void *)binary->name);
60                         pa_xfree ((void *)binary->resdef);
61                 }
62                 pa_hashmap_free (ns->binaries);
63
64                 for (i = 0;  i < APCLASS_DIM;  i++)
65                         pa_xfree((void *)ns->class_name[i]);
66
67                 free(ns);
68         }
69 }
70
71 int agl_nodeset_add_role (struct userdata *u, const char *role, agl_node_type type, agl_nodeset_resdef *resdef)
72 {
73         agl_nodeset *ns;
74         agl_nodeset_map *map;
75
76         pa_assert (u);
77         pa_assert_se (ns = u->nodeset);
78
79         map = pa_xnew0 (agl_nodeset_map, 1);
80         map->name = pa_xstrdup (role);
81         map->type = type;
82         map->role = pa_xstrdup (role);
83
84         if (resdef) {
85                 map->resdef = pa_xnew (agl_nodeset_resdef, 1);
86                 memcpy (map->resdef, resdef, sizeof(agl_nodeset_resdef));
87         }
88
89         return pa_hashmap_put (ns->roles, (void *)map->name, map);
90 }
91
92 agl_node *agl_node_create (struct userdata *u, agl_node *data)
93 {
94         agl_nodeset *ns;
95         agl_node *node;
96
97         pa_assert (u);
98         pa_assert_se (ns = u->nodeset);
99
100         node = pa_xnew0 (agl_node, 1);
101
102         pa_idxset_put (ns->nodes, node, &node->index);
103
104         if (data) {
105                 node->key = pa_xstrdup (data->key);
106                 node->direction = data->direction;
107                 node->implement = data->implement;
108                 node->channels = data->channels;
109                 node->location = data->location;
110                 node->privacy = data->privacy;
111                 node->type = data->type;
112                 node->zone = pa_xstrdup (data->zone);
113                 node->visible = data->visible;
114                 node->available = data->available;
115                 node->amname = pa_xstrdup (data->amname ? data->amname : data->paname);
116                 node->amdescr = pa_xstrdup(data->amdescr ? data->amdescr : "");
117                 node->amid = data->amid;
118                 node->paname = pa_xstrdup (data->paname);
119                 node->stamp = data->stamp;
120                 node->rset.id = data->rset.id ? pa_xstrdup(data->rset.id) : NULL;
121                 node->rset.grant = data->rset.grant;
122
123                 if (node->implement == agl_device) {
124                         node->pacard.index = data->pacard.index;
125                         if (data->pacard.profile)
126                                 node->pacard.profile = pa_xstrdup (data->pacard.profile);
127                         if (data->paport)
128                                 node->paport = data->paport;
129                 }
130         }
131
132          /* TODO : register the node to the router */
133         /* agl_router_register_node (u, node); */
134
135         return node;
136 }
137
138 const char *agl_node_type_str (agl_node_type type)
139 {
140         switch (type) {
141                 case agl_node_type_unknown: return "Unknown";
142                 case agl_radio:             return "Radio";
143                 case agl_player:            return "Player";
144                 case agl_navigator:         return "Navigator";
145                 case agl_game:              return "Game";
146                 case agl_browser:           return "Browser";
147                 case agl_camera:            return "Camera";
148                 case agl_phone:             return "Phone";
149                 case agl_alert:             return "Alert";
150                 case agl_event:             return "Event";
151                 case agl_system:            return "System";
152                 default:                    return "default";
153         }
154 }
155
156 const char *agl_node_direction_str (agl_direction direction)
157 {
158         switch (direction) {
159                 case agl_direction_unknown: return "unknown";
160                 case agl_input:             return "input";
161                 case agl_output:            return "output";
162                 default:                    return "< ??? >";
163         }
164 }
165
166 agl_node *agl_node_get_from_data (struct userdata *u, agl_direction type, void *data)
167 {
168         pa_sink_input_new_data *sinp_data;
169         pa_source_output_new_data *sout_data;
170         agl_nodeset *nodeset;
171         agl_node *node;
172         uint32_t index;
173
174         pa_assert (u);
175         pa_assert (data);
176         pa_assert (nodeset = u->nodeset);
177
178         pa_assert (type == agl_input || type == agl_output);
179
180         /* input (= sink_input) */
181         if (type == agl_input) {
182                 sinp_data = (pa_sink_input_new_data *) data;
183                 PA_IDXSET_FOREACH(node, nodeset->nodes, index) {
184                         if (node->client == sinp_data->client)
185                                 return node;
186                 }
187         /* output (= source_output) TODO */
188         /*} else {*/
189         }
190
191         return NULL;
192 }
193
194 agl_node *agl_node_get_from_client (struct userdata *u, pa_client *client)
195 {
196         agl_nodeset *nodeset;
197         agl_node *node;
198         uint32_t index;
199
200         pa_assert (u);
201         pa_assert (client);
202         pa_assert (nodeset = u->nodeset);
203
204         PA_IDXSET_FOREACH(node, nodeset->nodes, index) {
205                 if (node->client == client)
206                         return node;
207         }
208
209         return NULL;
210 }