fix the spec
[profile/ivi/ofono.git] / src / audio-settings.c
1 /*
2  *
3  *  oFono - Open Source Telephony
4  *
5  *  Copyright (C) 2008-2011  Intel Corporation. All rights reserved.
6  *
7  *  This program is free software; you can redistribute it and/or modify
8  *  it under the terms of the GNU General Public License veasion 2 as
9  *  published by the Free Software Foundation.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program; if not, write to the Free Software
18  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27 #include <stdio.h>
28 #include <errno.h>
29
30 #include <glib.h>
31 #include <gdbus.h>
32
33 #include "ofono.h"
34 #include "common.h"
35
36 static GSList *g_drivers = NULL;
37
38 struct ofono_audio_settings {
39         ofono_bool_t active;
40         char *mode;
41         const struct ofono_audio_settings_driver *driver;
42         void *driver_data;
43         struct ofono_atom *atom;
44 };
45
46 void ofono_audio_settings_active_notify(struct ofono_audio_settings *as,
47                                         ofono_bool_t active)
48 {
49         const char *path = __ofono_atom_get_path(as->atom);
50         DBusConnection *conn = ofono_dbus_get_connection();
51
52         if (as->active == active)
53                 return;
54
55         DBG("active %d", active);
56
57         as->active = active;
58
59         ofono_dbus_signal_property_changed(conn, path,
60                                 OFONO_AUDIO_SETTINGS_INTERFACE,
61                                 "Active", DBUS_TYPE_BOOLEAN, &as->active);
62
63 }
64
65 void ofono_audio_settings_mode_notify(struct ofono_audio_settings *as,
66                                                 const char *mode)
67 {
68         const char *path = __ofono_atom_get_path(as->atom);
69         DBusConnection *conn = ofono_dbus_get_connection();
70
71         DBG("mode %s", mode);
72
73         g_free(as->mode);
74         as->mode = g_strdup(mode);
75
76         if (as->mode == NULL)
77                 return;
78
79         ofono_dbus_signal_property_changed(conn, path,
80                                 OFONO_AUDIO_SETTINGS_INTERFACE,
81                                 "Mode", DBUS_TYPE_STRING, &as->mode);
82 }
83
84 static DBusMessage *audio_get_properties_reply(DBusMessage *msg,
85                                         struct ofono_audio_settings *as)
86 {
87         DBusMessage *reply;
88         DBusMessageIter iter;
89         DBusMessageIter dict;
90
91         reply = dbus_message_new_method_return(msg);
92         if (reply == NULL)
93                 return NULL;
94
95         dbus_message_iter_init_append(reply, &iter);
96
97         dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
98                                         OFONO_PROPERTIES_ARRAY_SIGNATURE,
99                                         &dict);
100
101         ofono_dbus_dict_append(&dict, "Active", DBUS_TYPE_BOOLEAN, &as->active);
102
103         if (as->mode)
104                 ofono_dbus_dict_append(&dict, "Mode",
105                                         DBUS_TYPE_STRING, &as->mode);
106
107         dbus_message_iter_close_container(&iter, &dict);
108
109         return reply;
110 }
111
112 static DBusMessage *audio_get_properties(DBusConnection *conn,
113                                                 DBusMessage *msg, void *data)
114 {
115         struct ofono_audio_settings *as = data;
116
117         return audio_get_properties_reply(msg, as);
118 }
119
120 static const GDBusMethodTable audio_methods[] = {
121         { GDBUS_ASYNC_METHOD("GetProperties",
122                                 NULL, GDBUS_ARGS({ "properties", "a{sv}" }),
123                                 audio_get_properties) },
124         { }
125 };
126
127 static const GDBusSignalTable audio_signals[] = {
128         { GDBUS_SIGNAL("PropertyChanged",
129                         GDBUS_ARGS({ "name", "s" }, { "value", "v" })) },
130         { }
131 };
132
133 int ofono_audio_settings_driver_register(const struct ofono_audio_settings_driver *d)
134 {
135         DBG("driver: %p, name: %s", d, d->name);
136
137         if (d->probe == NULL)
138                 return -EINVAL;
139
140         g_drivers = g_slist_prepend(g_drivers, (void *) d);
141
142         return 0;
143 }
144
145 void ofono_audio_settings_driver_unregister(const struct ofono_audio_settings_driver *d)
146 {
147         DBG("driver: %p, name: %s", d, d->name);
148
149         g_drivers = g_slist_remove(g_drivers, (void *) d);
150 }
151
152 static void audio_settings_unregister(struct ofono_atom *atom)
153 {
154         struct ofono_audio_settings *as = __ofono_atom_get_data(atom);
155         const char *path = __ofono_atom_get_path(as->atom);
156         DBusConnection *conn = ofono_dbus_get_connection();
157         struct ofono_modem *modem = __ofono_atom_get_modem(as->atom);
158
159         ofono_modem_remove_interface(modem, OFONO_AUDIO_SETTINGS_INTERFACE);
160         g_dbus_unregister_interface(conn, path, OFONO_AUDIO_SETTINGS_INTERFACE);
161 }
162
163 static void audio_settings_remove(struct ofono_atom *atom)
164 {
165         struct ofono_audio_settings *as = __ofono_atom_get_data(atom);
166
167         DBG("atom: %p", atom);
168
169         if (as == NULL)
170                 return;
171
172         if (as->driver && as->driver->remove)
173                 as->driver->remove(as);
174
175         g_free(as->mode);
176         g_free(as);
177 }
178
179 struct ofono_audio_settings *ofono_audio_settings_create(struct ofono_modem *modem,
180                                                         unsigned int vendor,
181                                                         const char *driver,
182                                                         void *data)
183 {
184         struct ofono_audio_settings *as;
185         GSList *l;
186
187         if (driver == NULL)
188                 return NULL;
189
190         as = g_try_new0(struct ofono_audio_settings, 1);
191         if (as == NULL)
192                 return NULL;
193
194         as->atom = __ofono_modem_add_atom(modem, OFONO_ATOM_TYPE_AUDIO_SETTINGS,
195                                                 audio_settings_remove, as);
196
197         for (l = g_drivers; l; l = l->next) {
198                 const struct ofono_audio_settings_driver *drv = l->data;
199
200                 if (g_strcmp0(drv->name, driver) != 0)
201                         continue;
202
203                 if (drv->probe(as, vendor, data) < 0)
204                         continue;
205
206                 as->driver = drv;
207                 break;
208         }
209
210         return as;
211 }
212
213 void ofono_audio_settings_register(struct ofono_audio_settings *as)
214 {
215         DBusConnection *conn = ofono_dbus_get_connection();
216         struct ofono_modem *modem = __ofono_atom_get_modem(as->atom);
217         const char *path = __ofono_atom_get_path(as->atom);
218
219         if (!g_dbus_register_interface(conn, path,
220                                         OFONO_AUDIO_SETTINGS_INTERFACE,
221                                         audio_methods, audio_signals,
222                                         NULL, as, NULL)) {
223                 ofono_error("Could not create %s interface",
224                                 OFONO_AUDIO_SETTINGS_INTERFACE);
225
226                 return;
227         }
228
229         ofono_modem_add_interface(modem, OFONO_AUDIO_SETTINGS_INTERFACE);
230         __ofono_atom_register(as->atom, audio_settings_unregister);
231 }
232
233 void ofono_audio_settings_remove(struct ofono_audio_settings *as)
234 {
235         __ofono_atom_free(as->atom);
236 }
237
238 void ofono_audio_settings_set_data(struct ofono_audio_settings *as, void *data)
239 {
240         as->driver_data = data;
241 }
242
243 void *ofono_audio_settings_get_data(struct ofono_audio_settings *as)
244 {
245         return as->driver_data;
246 }
247
248 struct ofono_modem *ofono_audio_settings_get_modem(struct ofono_audio_settings *as)
249 {
250         return __ofono_atom_get_modem(as->atom);
251 }