diff options
-rw-r--r-- | audio/audio.conf | 3 | ||||
-rw-r--r-- | audio/headset.c | 4 | ||||
-rw-r--r-- | audio/manager.c | 39 | ||||
-rw-r--r-- | audio/manager.h | 2 |
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); |