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