summaryrefslogtreecommitdiffstats
path: root/audio/manager.c
diff options
context:
space:
mode:
Diffstat (limited to 'audio/manager.c')
-rw-r--r--audio/manager.c140
1 files changed, 123 insertions, 17 deletions
diff --git a/audio/manager.c b/audio/manager.c
index d8872968..316dd5cc 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -32,8 +32,13 @@
#include <unistd.h>
#include <stdint.h>
#include <assert.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <ctype.h>
#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
@@ -44,7 +49,7 @@
#include "dbus-helper.h"
#include "logging.h"
-
+#include "textfile.h"
#include "manager.h"
#include "error.h"
@@ -92,7 +97,7 @@ static struct device *find_device(bdaddr_t *bda)
for (l = devices; l != NULL; l = l->next) {
struct device *device = l->data;
- if (bacmp(&device->bda, bda) == 0)
+ if (bacmp(&device->dst, bda) == 0)
return device;
}
@@ -118,12 +123,18 @@ static void remove_device(struct device *device)
static gboolean add_device(struct device *device)
{
+ gboolean is_default;
+
/* First device became default */
if (g_slist_length(devices) == 0)
default_dev = device;
devices = g_slist_append(devices, device);
+ is_default = default_dev == device ? TRUE : FALSE;
+
+ device_store(device, is_default);
+
return TRUE;
}
@@ -446,7 +457,7 @@ static void get_next_record(struct audio_sdp_data *data)
data->handles = g_slist_remove(data->handles, data->handles->data);
- ba2str(&data->device->bda, address);
+ ba2str(&data->device->dst, address);
dbus_message_append_args(msg, DBUS_TYPE_STRING, &ptr,
DBUS_TYPE_UINT32, handle,
@@ -561,7 +572,7 @@ static DBusHandlerResult get_handles(const char *uuid,
goto failed;
}
- ba2str(&data->device->bda, address);
+ ba2str(&data->device->dst, address);
dbus_message_append_args(msg, DBUS_TYPE_STRING, &ptr,
DBUS_TYPE_STRING, &uuid,
@@ -658,27 +669,27 @@ struct device *manager_device_connected(bdaddr_t *bda)
static gboolean device_supports_interface(struct device *device,
const char *iface)
{
- if (strcmp(iface, AUDIO_HEADSET_INTERFACE) == 0)
- return device->headset ? TRUE : FALSE;
+ if (strcmp(iface, AUDIO_HEADSET_INTERFACE) == 0)
+ return device->headset ? TRUE : FALSE;
- if (strcmp(iface, AUDIO_GATEWAY_INTERFACE) == 0)
- return device->gateway ? TRUE : FALSE;
+ if (strcmp(iface, AUDIO_GATEWAY_INTERFACE) == 0)
+ return device->gateway ? TRUE : FALSE;
- if (strcmp(iface, AUDIO_SOURCE_INTERFACE) == 0)
- return device->source ? TRUE : FALSE;
+ if (strcmp(iface, AUDIO_SOURCE_INTERFACE) == 0)
+ return device->source ? TRUE : FALSE;
- if (strcmp(iface, AUDIO_SINK_INTERFACE) == 0)
+ if (strcmp(iface, AUDIO_SINK_INTERFACE) == 0)
return device->sink ? TRUE : FALSE;
- if (strcmp(iface, AUDIO_CONTROL_INTERFACE) == 0)
- return device->control ? TRUE : FALSE;
+ if (strcmp(iface, AUDIO_CONTROL_INTERFACE) == 0)
+ return device->control ? TRUE : FALSE;
- if (strcmp(iface, AUDIO_TARGET_INTERFACE) == 0)
- return device->target ? TRUE : FALSE;
+ if (strcmp(iface, AUDIO_TARGET_INTERFACE) == 0)
+ return device->target ? TRUE : FALSE;
- debug("Unknown interface %s", iface);
+ debug("Unknown interface %s", iface);
- return FALSE;
+ return FALSE;
}
static gboolean device_matches(struct device *device, char **interfaces)
@@ -1069,6 +1080,97 @@ static DBusSignalVTable manager_signals[] = {
{ NULL, NULL }
};
+static void parse_stored_devices(char *key, char *value, void *data)
+{
+ struct device *device;
+ bdaddr_t dst;
+ char addr[18];
+ char *ptr;
+ char ifaces[6][8];
+ int len, i;
+
+ if (!key || !value)
+ return;
+
+ /* Format: XX:XX:XX:XX:XX:XX interface0:interface1:... */
+ memset(addr, 0, 18);
+ strncpy(addr, key, 17);
+ str2ba(addr, &dst);
+
+ if ((device = create_device(&dst)) == NULL)
+ return;
+
+ /* Parsing the interface */
+ ptr = strchr(value, ':');
+
+ if (!ptr) {
+ strncpy(ifaces[0], value, 8);
+ if (strcmp(ifaces[0], "headset") == 0)
+ device->headset = headset_init(device, NULL, 0);
+ }
+
+ /* FIXME: has more than 1 interface */
+ for (i = 0; ptr && i < 6; i++) {
+ len = ptr-value;
+ strncpy(ifaces[i], value, len);
+ value = ptr;
+ ptr = strchr(ptr, ':');
+ }
+
+ add_device(device);
+}
+
+static void register_devices_stored(const char *adapter)
+{
+ char filename[PATH_MAX + 1];
+ char *addr;
+ struct stat s;
+ bdaddr_t src;
+ bdaddr_t dst;
+ bdaddr_t default_src;
+ int dev_id;
+
+ create_name(filename, PATH_MAX, STORAGEDIR, adapter, "audio");
+
+ str2ba(adapter, &src);
+
+ bacpy(&default_src, BDADDR_ANY);
+ dev_id = hci_get_route(NULL);
+ if (dev_id < 0)
+ hci_devba(dev_id, &default_src);
+
+ if (stat(filename, &s) == 0 && (s.st_mode & __S_IFREG)) {
+ textfile_foreach(filename, parse_stored_devices, &src);
+ addr = textfile_get(filename, "default");
+
+ str2ba(addr, &dst);
+ default_dev = find_device(&dst);
+ }
+}
+
+static void register_stored(void)
+{
+ char dirname[PATH_MAX + 1];
+ struct dirent *de;
+ DIR *dir;
+
+ snprintf(dirname, PATH_MAX, "%s", STORAGEDIR);
+
+ dir = opendir(dirname);
+ if (!dir)
+ return;
+
+ while ((de = readdir(dir)) != NULL) {
+ if (!isdigit(de->d_name[0]))
+ continue;
+
+ /* Device objects */
+ register_devices_stored(de->d_name);
+ }
+
+ closedir(dir);
+}
+
int audio_init(DBusConnection *conn)
{
if (!dbus_connection_create_object_path(conn, AUDIO_MANAGER_PATH,
@@ -1090,6 +1192,10 @@ int audio_init(DBusConnection *conn)
connection = dbus_connection_ref(conn);
+ info("Registered manager path:%s", AUDIO_MANAGER_PATH);
+
+ register_stored();
+
return 0;
}