Upgrade bluez5_37 :Merge the code from private
[platform/upstream/bluez.git] / android / sco.c
1 /*
2  *
3  *  BlueZ - Bluetooth protocol stack for Linux
4  *
5  *  Copyright (C) 2014 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 as published by
9  *  the Free Software Foundation; either version 2 of the License, or
10  *  (at your option) any later version.
11  *
12  *  This program is distributed in the hope that it will be useful,
13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  *  GNU General Public License for more details.
16  *
17  *  You should have received a copy of the GNU General Public License
18  *  along with this program; if not, write to the Free Software
19  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20  *
21  */
22
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <stdlib.h>
28 #include <stdbool.h>
29 #include <errno.h>
30
31 #include <glib.h>
32
33 #include "lib/bluetooth.h"
34 #include "btio/btio.h"
35 #include "src/log.h"
36 #include "src/shared/util.h"
37
38 #include "sco.h"
39
40 struct bt_sco {
41         int ref_count;
42
43         GIOChannel *server_io;
44
45         GIOChannel *io;
46         guint watch;
47
48         bdaddr_t local_addr;
49         bdaddr_t remote_addr;
50
51         bt_sco_confirm_func_t confirm_cb;
52         bt_sco_conn_func_t connect_cb;
53         bt_sco_disconn_func_t disconnect_cb;
54 };
55
56 /* We support only one sco for the moment */
57 static bool sco_in_use = false;
58
59 static void clear_remote_address(struct bt_sco *sco)
60 {
61         memset(&sco->remote_addr, 0, sizeof(bdaddr_t));
62 }
63
64 static gboolean disconnect_watch(GIOChannel *chan, GIOCondition cond,
65                                                         gpointer user_data)
66 {
67         struct bt_sco *sco = user_data;
68
69         g_io_channel_shutdown(sco->io, TRUE, NULL);
70         g_io_channel_unref(sco->io);
71         sco->io = NULL;
72
73         DBG("");
74
75         sco->watch = 0;
76
77         if (sco->disconnect_cb)
78                 sco->disconnect_cb(&sco->remote_addr);
79
80         clear_remote_address(sco);
81
82         return FALSE;
83 }
84
85 static void connect_sco_cb(GIOChannel *chan, GError *err, gpointer user_data)
86 {
87         struct bt_sco *sco = user_data;
88
89         DBG("");
90
91         /* Lets unref connecting io */
92         if (sco->io) {
93                 g_io_channel_unref(sco->io);
94                 sco->io = NULL;
95         }
96
97         if (err) {
98                 error("sco: Audio connect failed (%s)", err->message);
99
100                 /*
101                  * Connect_sco_cb is called only when connect_cb is in place
102                  * Therefore it is safe to call it
103                  */
104                 sco->connect_cb(SCO_STATUS_ERROR, &sco->remote_addr);
105
106                 clear_remote_address(sco);
107
108                 return;
109         }
110
111         g_io_channel_set_close_on_unref(chan, TRUE);
112
113         sco->io = g_io_channel_ref(chan);
114         sco->watch = g_io_add_watch(chan, G_IO_ERR | G_IO_HUP | G_IO_NVAL,
115                                                         disconnect_watch, sco);
116
117         /* It is safe to call it here */
118         sco->connect_cb(SCO_STATUS_OK, &sco->remote_addr);
119 }
120
121 static void confirm_sco_cb(GIOChannel *chan, gpointer user_data)
122 {
123         char address[18];
124         bdaddr_t bdaddr;
125         GError *err = NULL;
126         struct bt_sco *sco = user_data;
127         uint16_t voice_settings;
128
129         DBG("");
130
131         bt_io_get(chan, &err,
132                         BT_IO_OPT_DEST, address,
133                         BT_IO_OPT_DEST_BDADDR, &bdaddr,
134                         BT_IO_OPT_INVALID);
135         if (err) {
136                 error("sco: audio confirm failed (%s)", err->message);
137                 g_error_free(err);
138                 goto drop;
139         }
140
141         if (!sco->confirm_cb || !sco->connect_cb) {
142                 error("sco: Connect and/or confirm callback not registered ");
143                 goto drop;
144         }
145
146         /* Check if there is SCO */
147         if (sco->io) {
148                 error("sco: SCO is in progress");
149                 goto drop;
150         }
151
152         if (!sco->confirm_cb(&bdaddr, &voice_settings)) {
153                 error("sco: Audio connection from %s rejected", address);
154                 goto drop;
155         }
156
157         bacpy(&sco->remote_addr, &bdaddr);
158
159         DBG("Incoming SCO connection from %s, voice settings 0x%x", address,
160                                                                 voice_settings);
161
162         err = NULL;
163         bt_io_set(chan, &err, BT_IO_OPT_VOICE, voice_settings,
164                                                         BT_IO_OPT_INVALID);
165         if (err) {
166                 error("sco: Could not set voice settings (%s)", err->message);
167                 g_error_free(err);
168                 goto drop;
169         }
170
171         if (!bt_io_accept(chan, connect_sco_cb, sco, NULL, NULL)) {
172                 error("sco: Failed to accept audio connection");
173                 goto drop;
174         }
175
176         sco->io = g_io_channel_ref(chan);
177
178         return;
179
180 drop:
181         g_io_channel_shutdown(chan, TRUE, NULL);
182 }
183
184 static bool sco_listen(struct bt_sco *sco)
185 {
186         GError *err = NULL;
187
188         if (!sco)
189                 return false;
190
191         sco->server_io = bt_io_listen(NULL, confirm_sco_cb, sco, NULL, &err,
192                                                         BT_IO_OPT_SOURCE_BDADDR,
193                                                         &sco->local_addr,
194                                                         BT_IO_OPT_INVALID);
195         if (!sco->server_io) {
196                 error("sco: Failed to listen on SCO: %s", err->message);
197                 g_error_free(err);
198                 return false;
199         }
200
201         return true;
202 }
203
204 struct bt_sco *bt_sco_new(const bdaddr_t *local_bdaddr)
205 {
206         struct bt_sco *sco;
207
208         if (!local_bdaddr)
209                 return NULL;
210
211         /* For now we support only one SCO connection per time */
212         if (sco_in_use)
213                 return NULL;
214
215         sco = new0(struct bt_sco, 1);
216         if (!sco)
217                 return NULL;
218
219         bacpy(&sco->local_addr, local_bdaddr);
220
221         if (!sco_listen(sco)) {
222                 free(sco);
223                 return NULL;
224         }
225
226         sco_in_use  = true;
227
228         return bt_sco_ref(sco);
229 }
230
231 struct bt_sco *bt_sco_ref(struct bt_sco *sco)
232 {
233         if (!sco)
234                 return NULL;
235
236         __sync_fetch_and_add(&sco->ref_count, 1);
237
238         return sco;
239 }
240
241 static void sco_free(struct bt_sco *sco)
242 {
243         if (sco->server_io) {
244                 g_io_channel_shutdown(sco->server_io, TRUE, NULL);
245                 g_io_channel_unref(sco->server_io);
246         }
247
248         if (sco->io) {
249                 g_io_channel_shutdown(sco->io, TRUE, NULL);
250                 g_io_channel_unref(sco->io);
251         }
252
253         g_free(sco);
254         sco_in_use  = false;
255 }
256
257 void bt_sco_unref(struct bt_sco *sco)
258 {
259         DBG("");
260
261         if (!sco)
262                 return;
263
264         if (__sync_sub_and_fetch(&sco->ref_count, 1))
265                 return;
266
267         sco_free(sco);
268 }
269
270 bool bt_sco_connect(struct bt_sco *sco, const bdaddr_t *addr,
271                                                         uint16_t voice_settings)
272 {
273         GIOChannel *io;
274         GError *gerr = NULL;
275
276         DBG("");
277
278         if (!sco || !sco->connect_cb || !addr) {
279                 error("sco: Incorrect parameters or missing connect_cb");
280                 return false;
281         }
282
283         /* Check if we have connection in progress */
284         if (sco->io) {
285                 error("sco: Connection already in progress");
286                 return false;
287         }
288
289         io = bt_io_connect(connect_sco_cb, sco, NULL, &gerr,
290                                 BT_IO_OPT_SOURCE_BDADDR, &sco->local_addr,
291                                 BT_IO_OPT_DEST_BDADDR, addr,
292                                 BT_IO_OPT_VOICE, voice_settings,
293                                 BT_IO_OPT_INVALID);
294
295         if (!io) {
296                 error("sco: unable to connect audio: %s", gerr->message);
297                 g_error_free(gerr);
298                 return false;
299         }
300
301         sco->io = io;
302
303         bacpy(&sco->remote_addr, addr);
304
305         return true;
306 }
307
308 void bt_sco_disconnect(struct bt_sco *sco)
309 {
310         if (!sco)
311                 return;
312
313         if (sco->io)
314                 g_io_channel_shutdown(sco->io, TRUE, NULL);
315 }
316
317 bool bt_sco_get_fd_and_mtu(struct bt_sco *sco, int *fd, uint16_t *mtu)
318 {
319         GError *err;
320
321         if (!sco->io || !fd || !mtu)
322                 return false;
323
324         err = NULL;
325         if (!bt_io_get(sco->io, &err, BT_IO_OPT_MTU, mtu, BT_IO_OPT_INVALID)) {
326                         error("Unable to get MTU: %s\n", err->message);
327                         g_clear_error(&err);
328                         return false;
329                 }
330
331         *fd = g_io_channel_unix_get_fd(sco->io);
332
333         return true;
334 }
335
336 void bt_sco_set_confirm_cb(struct bt_sco *sco,
337                                         bt_sco_confirm_func_t func)
338 {
339         sco->confirm_cb = func;
340 }
341
342 void bt_sco_set_connect_cb(struct bt_sco *sco, bt_sco_conn_func_t func)
343 {
344         sco->connect_cb = func;
345 }
346
347 void bt_sco_set_disconnect_cb(struct bt_sco *sco,
348                                                 bt_sco_disconn_func_t func)
349 {
350         sco->disconnect_cb = func;
351 }