pump up version number and update changelog
[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 #include "resource.h"
67 #include "classify.h"
68
69 #ifndef DEFAULT_CONFIG_DIR
70 #define DEFAULT_CONFIG_DIR "/etc/pulse"
71 #endif
72
73 #ifndef DEFAULT_CONFIG_FILE
74 #define DEFAULT_CONFIG_FILE "murphy-ivi.lua"
75 #endif
76
77 #ifdef WITH_MURPHYIF
78 #define WITH_DOMCTL
79 #define WITH_RESOURCES
80 #endif
81
82
83 PA_MODULE_AUTHOR("Janos Kovacs");
84 PA_MODULE_DESCRIPTION("Murphy and GenIVI compliant audio policy module");
85 PA_MODULE_VERSION(PACKAGE_VERSION);
86 PA_MODULE_LOAD_ONCE(true);
87 PA_MODULE_USAGE(
88     "config_dir=<configuration directory>"
89     "config_file=<policy configuration file> "
90     "fade_out=<stream fade-out time in msec> "
91     "fade_in=<stream fade-in time in msec> "
92     "enable_multiplex=<boolean for disabling combine creation> "
93 #ifdef WITH_DOMCTL
94     "murphy_domain_controller=<address of Murphy's domain controller service> "
95 #endif
96 #ifdef WITH_RESOURCES
97     "murphy_resources=<address of Murphy's native resource service> "
98 #endif
99 #ifdef WITH_DBUS
100     "dbus_bus_type=<system|session> "
101     "dbus_if_name=<policy dbus interface> "
102     "dbus_murphy_path=<policy daemon's path> "
103     "dbus_murphy_name=<policy daemon's name> "
104     "dbus_audiomgr_path=<GenIVI audio manager's path> " 
105     "dbus_audiomgr_name=<GenIVI audio manager's name> " 
106 #else
107     "audiomgr_socktype=<tcp|unix> "
108     "audiomgr_address=<audiomgr socket address> "
109     "audiomgr_port=<audiomgr tcp port> "
110 #endif
111     "null_sink_name=<name of the null sink> "
112 );
113
114 static const char* const valid_modargs[] = {
115     "config_dir",
116     "config_file",
117     "fade_out",
118     "fade_in",
119     "enable_multiplex",
120 #ifdef WITH_DOMCTL
121     "murphy_domain_controller",
122 #endif
123 #ifdef WITH_RESOURCES
124     "murphy_resources",
125 #endif
126 #ifdef WITH_DBUS
127     "dbus_bus_type",
128     "dbus_if_name",
129     "dbus_murphy_path",
130     "dbus_murphy_name",
131     "dbus_audiomgr_path",
132     "dbus_audiomgr_name",
133 #else
134     "audiomgr_socktype",
135     "audiomgr_address",
136     "audiomgr_port",
137 #endif
138     "null_sink_name",
139     NULL
140 };
141
142
143 int pa__init(pa_module *m) {
144     struct userdata *u = NULL;
145     pa_modargs      *ma = NULL;
146     const char      *cfgdir;
147     const char      *cfgfile;
148     const char      *fadeout;
149     const char      *fadein;
150 #ifdef WITH_DOMCTL
151     const char      *ctladdr;
152 #endif
153 #ifdef WITH_RESOURCES
154     const char      *resaddr;
155 #endif
156 #ifdef WITH_DBUS
157     const char      *dbustype;
158     const char      *ampath;
159     const char      *amnam;
160 #else
161     const char      *socktype;
162     const char      *amaddr;
163     const char      *amport;
164 #endif
165     const char      *nsnam;
166     const char      *cfgpath;
167     char             buf[4096];
168     bool             enable_multiplex = true;
169
170
171     pa_assert(m);
172
173     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
174         pa_log("Failed to parse module arguments.");
175         goto fail;
176     }
177
178     cfgdir   = pa_modargs_get_value(ma, "config_dir", DEFAULT_CONFIG_DIR);
179     cfgfile  = pa_modargs_get_value(ma, "config_file", DEFAULT_CONFIG_FILE);
180     fadeout  = pa_modargs_get_value(ma, "fade_out", NULL);
181     fadein   = pa_modargs_get_value(ma, "fade_in", NULL);
182
183     if (pa_modargs_get_value_boolean(ma, "enable_multiplex", &enable_multiplex) < 0)
184         enable_multiplex = true;
185
186 #ifdef WITH_DOMCTL
187     ctladdr  = pa_modargs_get_value(ma, "murphy_domain_controller", NULL);
188 #endif
189 #ifdef WITH_RESOURCES
190     resaddr  = pa_modargs_get_value(ma, "murphy_resources", NULL);
191 #endif
192 #ifdef WITH_DBUS
193     dbustype = pa_modargs_get_value(ma, "dbus_bus_type", NULL);
194     ampath   = pa_modargs_get_value(ma, "dbus_audiomgr_path", NULL);
195     amnam    = pa_modargs_get_value(ma, "dbus_audiomgr_name", NULL);
196 #else
197     socktype = pa_modargs_get_value(ma, "audiomgr_socktype", NULL);
198     amaddr   = pa_modargs_get_value(ma, "audiomgr_address", NULL);
199     amport   = pa_modargs_get_value(ma, "audiomgr_port", NULL);
200 #endif
201     nsnam    = pa_modargs_get_value(ma, "null_sink_name", NULL);
202
203     u = pa_xnew0(struct userdata, 1);
204     u->core      = m->core;
205     u->module    = m;
206     u->nullsink  = pa_utils_create_null_sink(u, nsnam);
207     u->zoneset   = pa_zoneset_init(u);
208     u->nodeset   = pa_nodeset_init(u);
209     u->audiomgr  = pa_audiomgr_init(u);
210 #ifdef WITH_DBUS
211     u->routerif  = pa_routerif_init(u, dbustype, ampath, amnam);
212 #else
213     u->routerif  = pa_routerif_init(u, socktype, amaddr, amport);
214 #endif
215     u->discover  = pa_discover_init(u);
216     u->tracker   = pa_tracker_init(u);
217     u->router    = pa_router_init(u);
218     u->constrain = pa_constrain_init(u);
219     u->multiplex = pa_multiplex_init();
220     u->loopback  = pa_loopback_init();
221     u->fader     = pa_fader_init(fadeout, fadein);
222     u->volume    = pa_mir_volume_init(u);
223     u->scripting = pa_scripting_init(u);
224     u->config    = pa_mir_config_init(u);
225     u->extapi    = pa_extapi_init(u);
226     u->murphyif  = pa_murphyif_init(u, ctladdr, resaddr);
227     u->resource  = pa_resource_init(u);
228
229     u->state.sink   = PA_IDXSET_INVALID;
230     u->state.source = PA_IDXSET_INVALID;
231
232     u->enable_multiplex = enable_multiplex;
233
234     if (u->nullsink == NULL || u->routerif == NULL  ||
235         u->audiomgr == NULL || u->discover == NULL  ||
236         u->murphyif == NULL)
237         goto fail;
238
239     m->userdata = u;
240
241     /* register ext api callback */
242     u->protocol = pa_native_protocol_get(m->core);
243     pa_native_protocol_install_ext(u->protocol, m, extension_cb);
244
245     cfgpath = pa_utils_file_path(cfgdir, cfgfile, buf, sizeof(buf));
246
247     pa_mir_config_parse_file(u, cfgpath);
248
249     pa_tracker_synchronize(u);
250
251     mir_router_print_rtgroups(u, buf, sizeof(buf));
252     pa_log_debug("%s", buf);
253
254     pa_modargs_free(ma);
255
256     return 0;
257
258  fail:
259
260     if (ma)
261         pa_modargs_free(ma);
262
263     pa__done(m);
264
265     return -1;
266 }
267
268 void pa__done(pa_module *m) {
269     struct userdata *u;
270
271     pa_assert(m);
272
273     if ((u = m->userdata)) {
274         pa_resource_done(u);
275         pa_murphyif_done(u);
276         pa_tracker_done(u);
277         pa_discover_done(u);
278         pa_constrain_done(u);
279         pa_router_done(u);
280         pa_audiomgr_done(u);
281         pa_routerif_done(u);
282         pa_fader_done(u);
283         pa_mir_volume_done(u);
284         pa_mir_config_done(u);
285         pa_nodeset_done(u);
286         pa_zoneset_done(u);
287         pa_scripting_done(u);
288         pa_utils_destroy_null_sink(u);
289
290         pa_loopback_done(u->loopback, u->core);
291         pa_multiplex_done(u->multiplex, u->core);
292
293         pa_extapi_done(u);
294
295         if (u->protocol) {
296             pa_native_protocol_remove_ext(u->protocol, m);
297             pa_native_protocol_unref(u->protocol);
298         }
299
300         pa_xfree(u);
301     }
302 }
303
304
305
306 /*
307  * Local Variables:
308  * c-basic-offset: 4
309  * indent-tabs-mode: nil
310  * End:
311  *
312  */
313
314