scripting: support for zone based routing in application classes
[profile/ivi/pulseaudio-module-murphy-ivi.git] / murphy / module-murphy-ivi.c
1 /*
2  * module-murphy-ivi -- PulseAudio module for providing audio routing support
3  * Copyright (c) 2012, Intel Corporation.
4  *
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.
8  *
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.
13  *
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,
17  * MA 02110-1301 USA.
18  *
19  */
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/stat.h>
23 #include <stdio.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <fcntl.h>
27 #include <unistd.h>
28 #include <limits.h>
29
30 #include <sys/types.h>
31 #include <sys/socket.h>
32
33 #include <pulsecore/pulsecore-config.h>
34
35 #include <pulse/timeval.h>
36 #include <pulse/xmalloc.h>
37
38 #include <pulsecore/macro.h>
39 #include <pulsecore/module.h>
40 #include <pulsecore/idxset.h>
41 #include <pulsecore/client.h>
42 #include <pulsecore/core-util.h>
43 #include <pulsecore/core-error.h>
44 #include <pulsecore/modargs.h>
45 #include <pulsecore/log.h>
46
47 #include "module-murphy-ivi-symdef.h"
48 #include "userdata.h"
49 #include "node.h"
50 #include "zone.h"
51 #include "tracker.h"
52 #include "discover.h"
53 #include "router.h"
54 #include "constrain.h"
55 #include "multiplex.h"
56 #include "loopback.h"
57 #include "fader.h"
58 #include "volume.h"
59 #include "audiomgr.h"
60 #include "routerif.h"
61 #include "murphy-config.h"
62 #include "utils.h"
63 #include "scripting.h"
64 #include "extapi.h"
65 #include "murphyif.h"
66
67 #ifndef DEFAULT_CONFIG_DIR
68 #define DEFAULT_CONFIG_DIR "/etc/pulse"
69 #endif
70
71 #ifndef DEFAULT_CONFIG_FILE
72 #define DEFAULT_CONFIG_FILE "murphy-ivi.lua"
73 #endif
74
75 #ifdef WITH_MURPHYIF
76 #define WITH_DOMCTL
77 #define WITH_RESOURCES
78 #endif
79
80
81 PA_MODULE_AUTHOR("Janos Kovacs");
82 PA_MODULE_DESCRIPTION("Murphy and GenIVI compliant audio policy module");
83 PA_MODULE_VERSION(PACKAGE_VERSION);
84 PA_MODULE_LOAD_ONCE(TRUE);
85 PA_MODULE_USAGE(
86     "config_dir=<configuration directory>"
87     "config_file=<policy configuration file> "
88     "fade_out=<stream fade-out time in msec> "
89     "fade_in=<stream fade-in time in msec> "
90 #ifdef WITH_DOMCTL
91     "murphy_domain_controller=<address of Murphy's domain controller service> "
92 #endif
93 #ifdef WITH_RESOURCES
94     "murphy_resources=<address of Murphy's native resource service> "
95 #endif
96 #ifdef WITH_DBUS
97     "dbus_bus_type=<system|session> "
98     "dbus_if_name=<policy dbus interface> "
99     "dbus_murphy_path=<policy daemon's path> "
100     "dbus_murphy_name=<policy daemon's name> "
101     "dbus_audiomgr_path=<GenIVI audio manager's path> " 
102     "dbus_audiomgr_name=<GenIVI audio manager's name> " 
103 #else
104     "audiomgr_socktype=<tcp|unix> "
105     "audiomgr_address=<audiomgr socket address> "
106     "audiomgr_port=<audiomgr tcp port> "
107 #endif
108     "null_sink_name=<name of the null sink> "
109 );
110
111 static const char* const valid_modargs[] = {
112     "config_dir",
113     "config_file",
114     "fade_out",
115     "fade_in",
116 #ifdef WITH_DOMCTL
117     "murphy_domain_controller",
118 #endif
119 #ifdef WITH_RESOURCES
120     "murphy_resources",
121 #endif
122 #ifdef WITH_DBUS
123     "dbus_bus_type",
124     "dbus_if_name",
125     "dbus_murphy_path",
126     "dbus_murphy_name",
127     "dbus_audiomgr_path",
128     "dbus_audiomgr_name",
129 #else
130     "audiomgr_socktype",
131     "audiomgr_address",
132     "audiomgr_port",
133 #endif
134     "null_sink_name",
135     NULL
136 };
137
138
139 int pa__init(pa_module *m) {
140     struct userdata *u = NULL;
141     pa_modargs      *ma = NULL;
142     const char      *cfgdir;
143     const char      *cfgfile;
144     const char      *fadeout;
145     const char      *fadein;
146 #ifdef WITH_DOMCTL
147     const char      *ctladdr;
148 #endif
149 #ifdef WITH_RESOURCES
150     const char      *resaddr;
151 #endif
152 #ifdef WITH_DBUS
153     const char      *dbustype;
154     const char      *ifnam;
155     const char      *mrppath;
156     const char      *mrpnam;
157     const char      *ampath;
158     const char      *amnam;
159 #else
160     const char      *socktype;
161     const char      *amaddr;
162     const char      *amport;
163 #endif
164     const char      *nsnam;
165     const char      *cfgpath;
166     char             buf[4096];
167
168     
169     pa_assert(m);
170     
171     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
172         pa_log("Failed to parse module arguments.");
173         goto fail;
174     }
175
176     cfgdir   = pa_modargs_get_value(ma, "config_dir", DEFAULT_CONFIG_DIR);
177     cfgfile  = pa_modargs_get_value(ma, "config_file", DEFAULT_CONFIG_FILE);
178     fadeout  = pa_modargs_get_value(ma, "fade_out", NULL);
179     fadein   = pa_modargs_get_value(ma, "fade_in", NULL);
180 #ifdef WITH_DOMCTL
181     ctladdr  = pa_modargs_get_value(ma, "murphy_domain_controller", NULL);
182 #endif
183 #ifdef WITH_RESOURCES
184     resaddr  = pa_modargs_get_value(ma, "murphy_resources", NULL);
185 #endif
186 #ifdef WITH_DBUS
187     dbustype = pa_modargs_get_value(ma, "dbus_bus_type", NULL);
188     ifnam    = pa_modargs_get_value(ma, "dbus_if_name", NULL);
189     mrppath  = pa_modargs_get_value(ma, "dbus_murphy_path", NULL);
190     mrpnam   = pa_modargs_get_value(ma, "dbus_murphy_name", NULL);
191     ampath   = pa_modargs_get_value(ma, "dbus_audiomgr_path", NULL);
192     amnam    = pa_modargs_get_value(ma, "dbus_audiomgr_name", NULL);
193 #else
194     socktype = pa_modargs_get_value(ma, "audiomgr_socktype", NULL);
195     amaddr   = pa_modargs_get_value(ma, "audiomgr_address", NULL);
196     amport   = pa_modargs_get_value(ma, "audiomgr_port", NULL);
197 #endif
198     nsnam    = pa_modargs_get_value(ma, "null_sink_name", NULL);
199
200     u = pa_xnew0(struct userdata, 1);
201     u->core      = m->core;
202     u->module    = m;
203     u->nullsink  = pa_utils_create_null_sink(u, nsnam);
204     u->zoneset   = pa_zoneset_init(u);
205     u->nodeset   = pa_nodeset_init(u);
206     u->audiomgr  = pa_audiomgr_init(u);
207 #ifdef WITH_DBUS
208     u->routerif  = pa_routerif_init(u, dbustype, ifnam, mrppath, mrpnam,
209                                     ampath, amnam);
210 #else
211     u->routerif  = pa_routerif_init(u, socktype, amaddr, amport);
212 #endif
213     u->discover  = pa_discover_init(u);
214     u->tracker   = pa_tracker_init(u);
215     u->router    = pa_router_init(u);
216     u->constrain = pa_constrain_init(u);
217     u->multiplex = pa_multiplex_init();
218     u->loopback  = pa_loopback_init();
219     u->fader     = pa_fader_init(fadeout, fadein);
220     u->volume    = pa_mir_volume_init(u);
221     u->scripting = pa_scripting_init(u);
222     u->config    = pa_mir_config_init(u);
223     u->extapi    = pa_extapi_init(u);
224     u->murphyif  = pa_murphyif_init(u, ctladdr, resaddr);
225
226     u->state.sink   = PA_IDXSET_INVALID;
227     u->state.source = PA_IDXSET_INVALID;
228
229     if (u->nullsink == NULL || u->routerif == NULL  ||
230         u->audiomgr == NULL || u->discover == NULL  ||
231         u->murphyif == NULL)
232         goto fail;
233
234     m->userdata = u;
235
236     /* register ext api callback */
237     u->protocol = pa_native_protocol_get(m->core);
238     pa_native_protocol_install_ext(u->protocol, m, extension_cb);
239
240     cfgpath = pa_utils_file_path(cfgdir, cfgfile, buf, sizeof(buf));
241
242     pa_mir_config_parse_file(u, cfgpath);
243
244     pa_tracker_synchronize(u);
245
246     mir_router_print_rtgroups(u, buf, sizeof(buf));
247     pa_log_debug("%s", buf);
248     
249     pa_modargs_free(ma);
250     
251     return 0;
252     
253  fail:
254     
255     if (ma)
256         pa_modargs_free(ma);
257     
258     pa__done(m);
259     
260     return -1;
261 }
262
263 void pa__done(pa_module *m) {
264     struct userdata *u;
265
266     pa_assert(m);
267     
268     if ((u = m->userdata)) {
269         pa_murphyif_done(u);
270         pa_tracker_done(u);
271         pa_discover_done(u);
272         pa_constrain_done(u);
273         pa_router_done(u);
274         pa_audiomgr_done(u);
275         pa_routerif_done(u);
276         pa_fader_done(u);
277         pa_mir_volume_done(u);
278         pa_mir_config_done(u);
279         pa_nodeset_done(u);
280         pa_zoneset_done(u);
281         pa_scripting_done(u);
282         pa_utils_destroy_null_sink(u);
283
284         pa_loopback_done(u->loopback, u->core);
285         pa_multiplex_done(u->multiplex, u->core);
286
287         pa_extapi_done(u);
288
289         if (u->protocol) {
290             pa_native_protocol_remove_ext(u->protocol, m);
291             pa_native_protocol_unref(u->protocol);
292         }
293
294         pa_xfree(u);
295     }
296 }
297
298
299
300 /*
301  * Local Variables:
302  * c-basic-offset: 4
303  * indent-tabs-mode: nil
304  * End:
305  *
306  */
307
308