device.c revision de72271829f6bfd21aa6550a2ac6d81e35b53cad
1/*
2 *
3 *  BlueZ - Bluetooth protocol stack for Linux
4 *
5 *  Copyright (C) 2006-2007  Nokia Corporation
6 *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
7 *
8 *
9 *  This program is free software; you can redistribute it and/or modify
10 *  it under the terms of the GNU General Public License as published by
11 *  the Free Software Foundation; either version 2 of the License, or
12 *  (at your option) any later version.
13 *
14 *  This program is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this program; if not, write to the Free Software
21 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22 *
23 */
24
25#ifdef HAVE_CONFIG_H
26#include <config.h>
27#endif
28
29#include <stdio.h>
30#include <errno.h>
31#include <unistd.h>
32#include <sys/stat.h>
33#include <netinet/in.h>
34
35#include <glib.h>
36#include <dbus/dbus.h>
37
38#include <bluetooth/bluetooth.h>
39#include <bluetooth/hci.h>
40#include <bluetooth/hci_lib.h>
41#include <bluetooth/sdp.h>
42#include <bluetooth/sdp_lib.h>
43
44#include "dbus.h"
45#include "dbus-helper.h"
46#include "logging.h"
47#include "textfile.h"
48
49#include "error.h"
50#include "ipc.h"
51#include "device.h"
52#include "avdtp.h"
53#include "control.h"
54#include "headset.h"
55#include "sink.h"
56
57static DBusHandlerResult device_get_address(DBusConnection *conn,
58						DBusMessage *msg, void *data)
59{
60	struct device *device = data;
61	DBusMessage *reply;
62	char address[18], *ptr = address;
63
64	reply = dbus_message_new_method_return(msg);
65	if (!reply)
66		return DBUS_HANDLER_RESULT_NEED_MEMORY;
67
68	ba2str(&device->dst, address);
69
70	dbus_message_append_args(reply, DBUS_TYPE_STRING, &ptr,
71							DBUS_TYPE_INVALID);
72
73	return send_message_and_unref(conn, reply);
74}
75
76static DBusHandlerResult device_get_name(DBusConnection *conn,
77						DBusMessage *msg, void *data)
78{
79	struct device *device = data;
80	DBusMessage *reply, *reply2, *msg2;
81	DBusError derr;
82	const char *name;
83	char address[18], *addr_ptr = address;
84
85	msg2 = dbus_message_new_method_call("org.bluez", device->adapter_path,
86					"org.bluez.Adapter", "GetRemoteName");
87	if (!msg2)
88		return DBUS_HANDLER_RESULT_NEED_MEMORY;
89
90	ba2str(&device->dst, address);
91	dbus_message_append_args(msg2, DBUS_TYPE_STRING, &addr_ptr,
92					DBUS_TYPE_INVALID);
93
94	dbus_error_init(&derr);
95	reply2 = dbus_connection_send_with_reply_and_block(conn, msg2, -1,
96								&derr);
97
98	dbus_message_unref(msg2);
99
100	if (dbus_error_is_set(&derr)) {
101		error("%s GetRemoteName(): %s", device->adapter_path,
102				derr.message);
103		dbus_error_free(&derr);
104		return err_failed(conn, msg, "Unable to get remote name");
105	}
106
107
108	reply = dbus_message_new_method_return(msg);
109	if (!reply)
110		return DBUS_HANDLER_RESULT_NEED_MEMORY;
111
112	dbus_message_get_args(reply2, NULL,
113		       		DBUS_TYPE_STRING, &name,
114				DBUS_TYPE_INVALID);
115
116	dbus_message_append_args(reply, DBUS_TYPE_STRING, &name,
117					DBUS_TYPE_INVALID);
118
119	dbus_message_unref(reply2);
120
121	return send_message_and_unref(conn, reply);
122}
123
124static DBusHandlerResult device_get_adapter(DBusConnection *conn,
125						DBusMessage *msg, void *data)
126{
127	struct device *device = data;
128	DBusMessage *reply;
129	char address[18], *ptr = address;
130
131	reply = dbus_message_new_method_return(msg);
132	if (!reply)
133		return DBUS_HANDLER_RESULT_NEED_MEMORY;
134
135	ba2str(&device->src, address);
136
137	dbus_message_append_args(reply, DBUS_TYPE_STRING, &ptr,
138							DBUS_TYPE_INVALID);
139
140	return send_message_and_unref(conn, reply);
141}
142
143
144static DBusHandlerResult device_get_connected(DBusConnection *conn,
145						DBusMessage *msg, void *data)
146{
147	DBusMessageIter iter, array_iter;
148	struct device *device = data;
149	DBusMessage *reply;
150	const char *iface;
151
152	reply = dbus_message_new_method_return(msg);
153	if (!reply)
154		return DBUS_HANDLER_RESULT_NEED_MEMORY;
155
156	dbus_message_iter_init_append(reply, &iter);
157
158	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
159						DBUS_TYPE_STRING_AS_STRING,
160						&array_iter);
161
162	if (device->headset &&
163			headset_get_state(device) >= HEADSET_STATE_CONNECTED) {
164		iface = AUDIO_HEADSET_INTERFACE;
165		dbus_message_iter_append_basic(&array_iter,
166						DBUS_TYPE_STRING, &iface);
167	}
168
169	dbus_message_iter_close_container(&iter, &array_iter);
170
171	return send_message_and_unref(conn, reply);
172}
173
174static DBusMethodVTable device_methods[] = {
175	{ "GetAddress",			device_get_address,	"",	"s" },
176	{ "GetName",			device_get_name,	"",	"s" },
177	{ "GetAdapter",			device_get_adapter,	"",	"s" },
178	{ "GetConnectedInterfaces",	device_get_connected,	"",	"as" },
179	{ NULL, NULL, NULL, NULL }
180};
181
182static void device_free(struct device *dev)
183{
184	if (dev->headset)
185		headset_free(dev);
186
187	if (dev->sink)
188		sink_free(dev);
189
190	if (dev->control)
191		control_free(dev);
192
193	if (dev->conn)
194		dbus_connection_unref(dev->conn);
195
196	if (dev->adapter_path)
197		g_free(dev->adapter_path);
198
199	if (dev->path)
200		g_free(dev->path);
201
202	g_free(dev);
203}
204
205static void device_unregister(DBusConnection *conn, void *data)
206{
207	struct device *device = data;
208
209	info("Unregistered device path:%s", device->path);
210
211	device_free(device);
212}
213
214char *find_adapter(DBusConnection *conn, bdaddr_t *src)
215{
216	DBusMessage *msg, *reply;
217	DBusError derr;
218	char address[18], *addr_ptr = address;
219	char *path, *ret;
220
221	msg = dbus_message_new_method_call("org.bluez", "/org/bluez",
222						"org.bluez.Manager",
223						"FindAdapter");
224	if (!msg) {
225		error("Unable to allocate new method call");
226		return NULL;
227	}
228
229	ba2str(src, address);
230
231	dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr,
232				 DBUS_TYPE_INVALID);
233
234	dbus_error_init(&derr);
235	reply = dbus_connection_send_with_reply_and_block(conn, msg, -1,
236								&derr);
237
238	dbus_message_unref(msg);
239
240	if (dbus_error_is_set(&derr) ||
241				dbus_set_error_from_message(&derr, reply)) {
242		error("FindAdapter(%s) failed: %s", address, derr.message);
243		dbus_error_free(&derr);
244		return NULL;
245	}
246
247	dbus_error_init(&derr);
248	dbus_message_get_args(reply, &derr,
249				DBUS_TYPE_STRING, &path,
250				DBUS_TYPE_INVALID);
251
252	if (dbus_error_is_set(&derr)) {
253		error("Unable to get message args");
254		dbus_message_unref(reply);
255		dbus_error_free(&derr);
256		return FALSE;
257	}
258
259	ret = g_strdup(path);
260
261	dbus_message_unref(reply);
262
263	debug("Got path %s for adapter with address %s", ret, address);
264
265	return ret;
266}
267
268struct device *device_register(DBusConnection *conn,
269					const char *path, bdaddr_t *bda)
270{
271	struct device *dev;
272	bdaddr_t src;
273	int dev_id;
274
275	if (!conn || !path)
276		return NULL;
277
278	bacpy(&src, BDADDR_ANY);
279	dev_id = hci_get_route(&src);
280	if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0))
281		return NULL;
282
283	dev = g_new0(struct device, 1);
284
285	dev->adapter_path = find_adapter(conn, &src);
286	if (!dev->adapter_path) {
287		device_free(dev);
288		return NULL;
289	}
290
291	if (!dbus_connection_create_object_path(conn, path, dev,
292							device_unregister)) {
293		error("D-Bus failed to register %s path", path);
294		device_free(dev);
295		return NULL;
296	}
297
298	if (!dbus_connection_register_interface(conn, path,
299			AUDIO_DEVICE_INTERFACE, device_methods, NULL, NULL)) {
300		error("Failed to register %s interface to %s",
301					AUDIO_DEVICE_INTERFACE, path);
302		dbus_connection_destroy_object_path(conn, path);
303		return NULL;
304	}
305
306	dev->path = g_strdup(path);
307	bacpy(&dev->dst, bda);
308	bacpy(&dev->src, &src);
309	bacpy(&dev->store, &src);
310	dev->conn = dbus_connection_ref(conn);
311
312	return dev;
313}
314
315int device_store(struct device *dev, gboolean is_default)
316{
317	char value[64];
318	char filename[PATH_MAX + 1];
319	char src_addr[18], dst_addr[18];
320	int offset = 0;
321
322	if (!dev->path)
323		return -EINVAL;
324
325	ba2str(&dev->dst, dst_addr);
326	ba2str(&dev->store, src_addr);
327
328	create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "audio");
329	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
330
331	if (is_default)
332		textfile_put(filename, "default", dst_addr);
333	if (dev->headset) {
334		snprintf(value, 64, "headset ");
335		offset += strlen("headset ");
336	}
337	if (dev->gateway) {
338		snprintf(value + offset, 64 - offset, "gateway ");
339		offset += strlen("gateway ");
340	}
341	if (dev->sink) {
342		snprintf(value + offset, 64 - offset, "sink ");
343		offset += strlen("sink ");
344	}
345	if (dev->source) {
346		snprintf(value + offset, 64 - offset, "source ");
347		offset += strlen("source ");
348	}
349	if (dev->control) {
350		snprintf(value + offset, 64 - offset, "control ");
351		offset += strlen("control ");
352	}
353	if (dev->target)
354		snprintf(value + offset, 64 - offset, "target");
355
356	return textfile_put(filename, dst_addr, value);
357}
358
359int device_remove_stored(struct device *dev)
360{
361	char filename[PATH_MAX + 1];
362	char src_addr[18], dst_addr[18];
363
364	ba2str(&dev->dst, dst_addr);
365	ba2str(&dev->store, src_addr);
366
367	create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "audio");
368
369	return textfile_del(filename, dst_addr);
370}
371
372void device_finish_sdp_transaction(struct device *dev)
373{
374	char address[18], *addr_ptr = address;
375	DBusMessage *msg, *reply;
376	DBusError derr;
377
378	ba2str(&dev->dst, address);
379
380	msg = dbus_message_new_method_call("org.bluez", dev->adapter_path,
381						"org.bluez.Adapter",
382						"FinishRemoteServiceTransaction");
383	if (!msg) {
384		error("Unable to allocate new method call");
385		return;
386	}
387
388	dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr,
389				 DBUS_TYPE_INVALID);
390
391	dbus_error_init(&derr);
392	reply = dbus_connection_send_with_reply_and_block(dev->conn,
393							msg, -1, &derr);
394
395	dbus_message_unref(msg);
396
397	if (dbus_error_is_set(&derr) ||
398				dbus_set_error_from_message(&derr, reply)) {
399		error("FinishRemoteServiceTransaction(%s) failed: %s",
400						address, derr.message);
401		dbus_error_free(&derr);
402		return;
403	}
404
405	dbus_message_unref(reply);
406}
407
408#if 0
409static avdtp_state_t ipc_to_avdtp_state(uint8_t ipc_state)
410{
411	switch (ipc_state) {
412	case STATE_DISCONNECTED:
413		return AVDTP_STATE_IDLE;
414	case STATE_CONNECTING:
415		return AVDTP_STATE_CONFIGURED;
416	case STATE_CONNECTED:
417		return AVDTP_STATE_OPEN;
418	case STATE_STREAM_STARTING:
419	case STATE_STREAMING:
420		return AVDTP_STATE_STREAMING;
421	default:
422		error("Unknown ipc state");
423		return AVDTP_STATE_IDLE;
424	}
425}
426
427static headset_state_t ipc_to_hs_state(uint8_t ipc_state)
428{
429	switch (ipc_state) {
430	case STATE_DISCONNECTED:
431		return HEADSET_STATE_DISCONNECTED;
432	case STATE_CONNECTING:
433		return HEADSET_STATE_CONNECT_IN_PROGRESS;
434	case STATE_CONNECTED:
435		return HEADSET_STATE_CONNECTED;
436	case STATE_STREAM_STARTING:
437		return HEADSET_STATE_PLAY_IN_PROGRESS;
438	case STATE_STREAMING:
439		return HEADSET_STATE_PLAYING;
440	default:
441		error("Unknown ipc state");
442		return HEADSET_STATE_DISCONNECTED;
443	}
444}
445#endif
446
447static uint8_t avdtp_to_ipc_state(avdtp_state_t state)
448{
449	switch (state) {
450	case AVDTP_STATE_IDLE:
451		return STATE_DISCONNECTED;
452	case AVDTP_STATE_CONFIGURED:
453		return STATE_CONNECTING;
454	case AVDTP_STATE_OPEN:
455		return STATE_CONNECTED;
456	case AVDTP_STATE_STREAMING:
457		return STATE_STREAMING;
458	default:
459		error("Unknown avdt state");
460		return AVDTP_STATE_IDLE;
461	}
462}
463
464static uint8_t hs_to_ipc_state(headset_state_t state)
465{
466	switch (state) {
467	case HEADSET_STATE_DISCONNECTED:
468		return STATE_DISCONNECTED;
469	case HEADSET_STATE_CONNECT_IN_PROGRESS:
470		return STATE_CONNECTING;
471	case HEADSET_STATE_CONNECTED:
472		return STATE_CONNECTED;
473	case HEADSET_STATE_PLAY_IN_PROGRESS:
474		return STATE_STREAMING;
475	default:
476		error("Unknown headset state");
477		return AVDTP_STATE_IDLE;
478	}
479}
480
481uint8_t device_get_state(struct device *dev)
482{
483	avdtp_state_t sink_state;
484	headset_state_t hs_state;
485
486	if (dev->sink && sink_is_active(dev)) {
487		sink_state = sink_get_state(dev);
488		return avdtp_to_ipc_state(sink_state);
489	}
490	else if (dev->headset && headset_is_active(dev)) {
491		hs_state = headset_get_state(dev);
492		return hs_to_ipc_state(hs_state);
493	}
494	else if (dev->control && control_is_active(dev))
495		return STATE_CONNECTED;
496
497	return STATE_DISCONNECTED;
498}
499
500gboolean device_is_connected(struct device *dev, const char *interface)
501{
502	if (!interface) {
503		if ((dev->sink || dev->source) &&
504			avdtp_is_connected(&dev->src, &dev->dst))
505			return TRUE;
506
507		if (dev->headset && headset_is_active(dev))
508			return TRUE;
509	}
510	else if (!strcmp(interface, AUDIO_SINK_INTERFACE) && dev->sink &&
511			avdtp_is_connected(&dev->src, &dev->dst))
512		return TRUE;
513	else if (!strcmp(interface, AUDIO_SOURCE_INTERFACE) && dev->source &&
514			avdtp_is_connected(&dev->src, &dev->dst))
515		return TRUE;
516	else if (!strcmp(interface, AUDIO_HEADSET_INTERFACE) && dev->headset &&
517			headset_is_active(dev))
518		return TRUE;
519	else if (!strcmp(interface, AUDIO_CONTROL_INTERFACE) && dev->headset &&
520			control_is_active(dev))
521		return TRUE;
522
523	return FALSE;
524}
525