summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-10-24 12:19:47 +0300
committerJohan Hedberg <johan.hedberg@nokia.com>2008-10-24 12:19:47 +0300
commite32c8dcd38b8e2282559a325c59fd6b7fa187d2f (patch)
tree7cb2b552730d295002fb42e55261a1cd4131a43c
parent93eccafca7bea1bc714e30561d18bcd51fda3b7c (diff)
Limit the amount of connected HSP/HFP devices and make it configurable
It's very tricky to get the multiple connected HSP/HFP devices use case right. E.g. in the case of in-band ringtone the specification mandates us to open SCO to the HFP before sending RING indications. So, in the case of multiple connected devices we would have to open multimple simultaneous SCO connections which simply isn't a wise thing to do.
-rw-r--r--audio/audio.conf3
-rw-r--r--audio/headset.c4
-rw-r--r--audio/manager.c39
-rw-r--r--audio/manager.h2
4 files changed, 48 insertions, 0 deletions
diff --git a/audio/audio.conf b/audio/audio.conf
index f50c826d..33a84e1e 100644
--- a/audio/audio.conf
+++ b/audio/audio.conf
@@ -23,6 +23,9 @@
# Defaults to false
HFP=false
+# Maximum number of connected HSP/HFP devices per adapter. Defaults to 1
+MaxConnections=1
+
# Just an example of potential config options for the other interfaces
#[A2DP]
#SBCSources=1
diff --git a/audio/headset.c b/audio/headset.c
index 77498d73..0a7f18ed 100644
--- a/audio/headset.c
+++ b/audio/headset.c
@@ -1466,6 +1466,10 @@ static DBusMessage *hs_connect(DBusConnection *conn, DBusMessage *msg,
return g_dbus_create_error(msg, ERROR_INTERFACE ".NotReady",
"Telephony subsystem not ready");
+ if (!manager_allow_headset_connection(&device->src))
+ return g_dbus_create_error(msg, ERROR_INTERFACE ".NotAllowed",
+ "Too many connected devices");
+
err = rfcomm_connect(device, NULL, NULL, NULL);
if (err < 0)
return g_dbus_create_error(msg, ERROR_INTERFACE
diff --git a/audio/manager.c b/audio/manager.c
index ae63b997..4441b90f 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -97,6 +97,7 @@ struct audio_adapter {
GIOChannel *hsp_hs_server;
};
+static int max_connected_headsets = 1;
static DBusConnection *connection = NULL;
static GKeyFile *config = NULL;
static GSList *adapters = NULL;
@@ -452,6 +453,9 @@ static void ag_io_cb(GIOChannel *chan, int err, const bdaddr_t *src,
if (!device)
goto drop;
+ if (!manager_allow_headset_connection(&device->src))
+ goto drop;
+
if (!device->headset)
btd_device_add_uuid(device->btd_dev, remote_uuid);
@@ -919,6 +923,16 @@ int audio_manager_init(DBusConnection *conn, GKeyFile *conf)
} else
enabled.hfp = b;
+ err = NULL;
+ i = g_key_file_get_integer(config, "Headset", "MaxConnected",
+ &err);
+ if (err) {
+ debug("audio.conf: %s", err->message);
+ g_error_free(err);
+ err = NULL;
+ } else
+ max_connected_headsets = i;
+
proceed:
if (enabled.headset) {
telephony_init();
@@ -1062,3 +1076,28 @@ struct audio_device *manager_get_device(const bdaddr_t *src,
return dev;
}
+
+gboolean manager_allow_headset_connection(bdaddr_t *src)
+{
+ GSList *l;
+ int connected = 0;
+
+ for (l = devices; l != NULL; l = l->next) {
+ struct audio_device *dev = l->data;
+ struct headset *hs = dev->headset;
+
+ if (bacmp(&dev->src, src))
+ continue;
+
+ if (!hs)
+ continue;
+
+ if (headset_get_state(dev) > HEADSET_STATE_DISCONNECTED)
+ connected++;
+
+ if (connected > max_connected_headsets)
+ return FALSE;
+ }
+
+ return TRUE;
+}
diff --git a/audio/manager.h b/audio/manager.h
index 6dfd7ef3..e56ec3b3 100644
--- a/audio/manager.h
+++ b/audio/manager.h
@@ -41,3 +41,5 @@ struct audio_device *manager_find_device(const bdaddr_t *bda, const char *interf
struct audio_device *manager_get_device(const bdaddr_t *src,
const bdaddr_t *dst);
+
+gboolean manager_allow_headset_connection(bdaddr_t *src);