calssification: more heuristics to guess bluetooth device 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 "tracker.h"
51 #include "discover.h"
52 #include "router.h"
53 #include "constrain.h"
54 #include "multiplex.h"
55 #include "loopback.h"
56 #include "volume.h"
57 #include "audiomgr.h"
58 #include "routerif.h"
59 #include "config.h"
60 #include "utils.h"
61
62 #ifndef DEFAULT_CONFIG_FILE
63 #define DEFAULT_CONFIG_FILE "murphy-ivi.conf"
64 #endif
65
66
67 PA_MODULE_AUTHOR("Janos Kovacs");
68 PA_MODULE_DESCRIPTION("Murphy and GenIVI compliant audio policy module");
69 PA_MODULE_VERSION(PACKAGE_VERSION);
70 PA_MODULE_LOAD_ONCE(TRUE);
71 PA_MODULE_USAGE(
72     "config_dir=<configuration directory>"
73     "config_file=<policy configuration file> "
74 #ifdef WITH_DBUS
75     "dbus_bus_type=<system|session> "
76     "dbus_if_name=<policy dbus interface> "
77     "dbus_murphy_path=<policy daemon's path> "
78     "dbus_murphy_name=<policy daemon's name> "
79     "dbus_audiomgr_path=<GenIVI audio manager's path> " 
80     "dbus_audiomgr_name=<GenIVI audio manager's name> " 
81 #else
82     "audiomgr_socktype=<tcp|unix> "
83     "audiomgr_address=<audiomgr socket address> "
84     "audiomgr_port=<audiomgr tcp port> "
85 #endif
86     "null_sink_name=<name of the null sink> "
87 );
88
89 static const char* const valid_modargs[] = {
90     "config_dir",
91     "config_file",
92 #ifdef WITH_DBUS
93     "dbus_bus_type",
94     "dbus_if_name",
95     "dbus_murphy_path",
96     "dbus_murphy_name",
97     "dbus_audiomgr_path",
98     "dbus_audiomgr_name",
99 #else
100     "audiomgr_socktype",
101     "audiomgr_address",
102     "audiomgr_port",
103 #endif
104     "null_sink_name",
105     NULL
106 };
107
108
109 int pa__init(pa_module *m) {
110     struct userdata *u = NULL;
111     pa_modargs      *ma = NULL;
112     const char      *cfgdir;
113     const char      *cfgfile;
114 #ifdef WITH_DBUS
115     const char      *dbustype;
116     const char      *ifnam;
117     const char      *mrppath;
118     const char      *mrpnam;
119     const char      *ampath;
120     const char      *amnam;
121 #else
122     const char      *socktype;
123     const char      *amaddr;
124     const char      *amport;
125 #endif
126     const char      *nsnam;
127     const char      *cfgpath;
128     char             buf[4096];
129     
130     pa_assert(m);
131     
132     if (!(ma = pa_modargs_new(m->argument, valid_modargs))) {
133         pa_log("Failed to parse module arguments.");
134         goto fail;
135     }
136
137     cfgdir   = pa_modargs_get_value(ma, "config_dir", NULL);
138     cfgfile  = pa_modargs_get_value(ma, "config_file", DEFAULT_CONFIG_FILE);
139 #ifdef WITH_DBUS
140     dbustype = pa_modargs_get_value(ma, "dbus_bus_type", NULL);
141     ifnam    = pa_modargs_get_value(ma, "dbus_if_name", NULL);
142     mrppath  = pa_modargs_get_value(ma, "dbus_murphy_path", NULL);
143     mrpnam   = pa_modargs_get_value(ma, "dbus_murphy_name", NULL);
144     ampath   = pa_modargs_get_value(ma, "dbus_audiomgr_path", NULL);
145     amnam    = pa_modargs_get_value(ma, "dbus_audiomgr_name", NULL);
146 #else
147     socktype = pa_modargs_get_value(ma, "audiomgr_socktype", NULL);
148     amaddr   = pa_modargs_get_value(ma, "audiomgr_address", NULL);
149     amport   = pa_modargs_get_value(ma, "audiomgr_port", NULL);
150 #endif
151     nsnam    = pa_modargs_get_value(ma, "null_sink_name", NULL);
152     
153     u = pa_xnew0(struct userdata, 1);
154     u->core      = m->core;
155     u->module    = m;
156     u->nullsink  = pa_utils_create_null_sink(u, nsnam);
157     u->nodeset   = pa_nodeset_init(u);
158     u->audiomgr  = pa_audiomgr_init(u);
159 #ifdef WITH_DBUS
160     u->routerif  = pa_routerif_init(u, dbustype, ifnam, mrppath, mrpnam,
161                                     ampath, amnam);
162 #else
163     u->routerif  = pa_routerif_init(u, socktype, amaddr, amport);
164 #endif
165     u->discover  = pa_discover_init(u);
166     u->tracker   = pa_tracker_init(u);
167     u->router    = pa_router_init(u);
168     u->constrain = pa_constrain_init(u);
169     u->multiplex = pa_multiplex_init();
170     u->loopback  = pa_loopback_init();
171     u->volume    = pa_mir_volume_init(u);
172     u->config    = pa_mir_config_init(u);
173
174     if (u->nullsink == NULL || u->routerif == NULL  ||
175         u->audiomgr == NULL || u->discover == NULL)
176         goto fail;
177
178     m->userdata = u;
179
180     //cfgpath = pa_utils_file_path(cfgfile, buf, sizeof(buf));
181     cfgpath = cfgfile;
182     pa_mir_config_parse_file(u, cfgpath);
183
184     pa_tracker_synchronize(u);
185
186     mir_router_print_rtgroups(u, buf, sizeof(buf));
187     pa_log_debug("%s", buf);
188     
189     pa_modargs_free(ma);
190     
191     return 0;
192     
193  fail:
194     
195     if (ma)
196         pa_modargs_free(ma);
197     
198     pa__done(m);
199     
200     return -1;
201 }
202
203 void pa__done(pa_module *m) {
204     struct userdata *u;
205
206     pa_assert(m);
207     
208     if ((u = m->userdata)) {
209     
210         pa_tracker_done(u);
211         pa_discover_done(u);
212         pa_constrain_done(u);
213         pa_router_done(u);
214         pa_audiomgr_done(u);
215         pa_routerif_done(u);
216         pa_mir_volume_done(u);
217         pa_mir_config_done(u);
218         pa_nodeset_done(u);
219         pa_utils_destroy_null_sink(u);
220
221         pa_loopback_done(u->loopback, u->core);
222         pa_multiplex_done(u->multiplex, u->core);
223
224         pa_xfree(u);
225     }
226 }
227
228
229
230 /*
231  * Local Variables:
232  * c-basic-offset: 4
233  * indent-tabs-mode: nil
234  * End:
235  *
236  */
237
238