summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2008-03-05 17:43:54 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2008-03-05 17:43:54 +0000
commitaa4ce3509e6bf62a20e89d680e2792388f0afde1 (patch)
tree18aa2354290c96b7d1a1c8a941463334414163a9
parent37c2fa54a9eb3d086849acdf4a4d64157334b21a (diff)
Do master role switching by default and add ForceMaster config option
-rw-r--r--audio/a2dp.c2
-rw-r--r--audio/audio.conf3
-rw-r--r--audio/avdtp.c22
-rw-r--r--audio/avdtp.h2
-rw-r--r--audio/control.c22
-rw-r--r--audio/control.h2
-rw-r--r--audio/manager.c46
7 files changed, 75 insertions, 24 deletions
diff --git a/audio/a2dp.c b/audio/a2dp.c
index fd3cb632..53922513 100644
--- a/audio/a2dp.c
+++ b/audio/a2dp.c
@@ -1100,7 +1100,7 @@ int a2dp_init(DBusConnection *conn, GKeyFile *config)
proceed:
connection = dbus_connection_ref(conn);
- avdtp_init();
+ avdtp_init(config);
if (source) {
for (i = 0; i < sbc_srcs; i++)
diff --git a/audio/audio.conf b/audio/audio.conf
index 07ed3ea4..393d9c20 100644
--- a/audio/audio.conf
+++ b/audio/audio.conf
@@ -4,6 +4,9 @@
# particular interface
[General]
+# Switch to master role for incoming connections (defaults to true)
+#ForceMaster=true
+
# If we want to disable support for specific services
# Defaults to supporting all implemented services
#Disable=Control,Source
diff --git a/audio/avdtp.c b/audio/avdtp.c
index 09e2b41a..22e042d4 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -2874,7 +2874,7 @@ static gboolean avdtp_server_cb(GIOChannel *chan, GIOCondition cond, void *data)
return TRUE;
}
-static GIOChannel *avdtp_server_socket(void)
+static GIOChannel *avdtp_server_socket(gboolean master)
{
int sock, lm;
struct sockaddr_l2 addr;
@@ -2887,6 +2887,10 @@ static GIOChannel *avdtp_server_socket(void)
}
lm = L2CAP_LM_SECURE;
+
+ if (master)
+ lm |= L2CAP_LM_MASTER;
+
if (setsockopt(sock, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) {
error("AVDTP server setsockopt: %s (%d)", strerror(errno),
errno);
@@ -2979,12 +2983,24 @@ void avdtp_get_peers(struct avdtp *session, bdaddr_t *src, bdaddr_t *dst)
bacpy(dst, &session->dst);
}
-int avdtp_init(void)
+int avdtp_init(GKeyFile *config)
{
+ GError *err = NULL;
+ gboolean tmp, master = TRUE;
+
if (avdtp_server)
return 0;
- avdtp_server = avdtp_server_socket();
+ tmp = g_key_file_get_boolean(config, "General", "ForceMaster",
+ &err);
+ if (err) {
+ debug("audio.conf: %s", err->message);
+ g_error_free(err);
+ err = NULL;
+ } else
+ master = tmp;
+
+ avdtp_server = avdtp_server_socket(master);
if (!avdtp_server)
return -1;
diff --git a/audio/avdtp.h b/audio/avdtp.h
index 4ae17508..4e938b6d 100644
--- a/audio/avdtp.h
+++ b/audio/avdtp.h
@@ -264,5 +264,5 @@ int avdtp_error_posix_errno(struct avdtp_error *err);
void avdtp_get_peers(struct avdtp *session, bdaddr_t *src, bdaddr_t *dst);
-int avdtp_init(void);
+int avdtp_init(GKeyFile *config);
void avdtp_exit(void);
diff --git a/audio/control.c b/audio/control.c
index 6085f587..2c8f03ba 100644
--- a/audio/control.c
+++ b/audio/control.c
@@ -309,7 +309,7 @@ static int avrcp_tg_record(sdp_buf_t *buf)
return ret;
}
-static GIOChannel *avctp_server_socket(void)
+static GIOChannel *avctp_server_socket(gboolean master)
{
int sock, lm;
struct sockaddr_l2 addr;
@@ -322,6 +322,10 @@ static GIOChannel *avctp_server_socket(void)
}
lm = L2CAP_LM_SECURE;
+
+ if (master)
+ lm |= L2CAP_LM_MASTER;
+
if (setsockopt(sock, SOL_L2CAP, L2CAP_LM, &lm, sizeof(lm)) < 0) {
error("AVCTP server setsockopt: %s (%d)", strerror(errno), errno);
close(sock);
@@ -975,13 +979,25 @@ void avrcp_disconnect(struct device *dev)
control->session = NULL;
}
-int avrcp_init(DBusConnection *conn)
+int avrcp_init(DBusConnection *conn, GKeyFile *config)
{
sdp_buf_t buf;
+ gboolean tmp, master = TRUE;
+ GError *err = NULL;
if (avctp_server)
return 0;
+
+ tmp = g_key_file_get_boolean(config, "General", "ForceMaster",
+ &err);
+ if (err) {
+ debug("audio.conf: %s", err->message);
+ g_error_free(err);
+ err = NULL;
+ } else
+ master = tmp;
+
connection = dbus_connection_ref(conn);
if (avrcp_tg_record(&buf) < 0) {
@@ -1010,7 +1026,7 @@ int avrcp_init(DBusConnection *conn)
return -1;
}
- avctp_server = avctp_server_socket();
+ avctp_server = avctp_server_socket(master);
if (!avctp_server)
return -1;
diff --git a/audio/control.h b/audio/control.h
index 7247949d..4f3b7e00 100644
--- a/audio/control.h
+++ b/audio/control.h
@@ -24,7 +24,7 @@
#define AUDIO_CONTROL_INTERFACE "org.bluez.audio.Control"
-int avrcp_init(DBusConnection *conn);
+int avrcp_init(DBusConnection *conn, GKeyFile *config);
void avrcp_exit(void);
gboolean avrcp_connect(struct device *dev);
diff --git a/audio/manager.c b/audio/manager.c
index c5f7df30..b59e9dbf 100644
--- a/audio/manager.c
+++ b/audio/manager.c
@@ -1485,7 +1485,7 @@ failed:
return TRUE;
}
-static GIOChannel *server_socket(uint8_t *channel)
+static GIOChannel *server_socket(uint8_t *channel, gboolean master)
{
int sock, lm;
struct sockaddr_rc addr;
@@ -1499,6 +1499,10 @@ static GIOChannel *server_socket(uint8_t *channel)
}
lm = RFCOMM_LM_SECURE;
+
+ if (master)
+ lm |= RFCOMM_LM_MASTER;
+
if (setsockopt(sock, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
error("server setsockopt: %s (%d)", strerror(errno), errno);
close(sock);
@@ -1540,14 +1544,36 @@ static int headset_server_init(DBusConnection *conn, GKeyFile *config)
{
uint8_t chan = DEFAULT_HS_AG_CHANNEL;
sdp_buf_t buf;
- gboolean hfp = TRUE;
+ gboolean hfp = TRUE, master = TRUE;
GError *err = NULL;
uint32_t features;
if (!(enabled.headset || enabled.gateway))
return 0;
- hs_server = server_socket(&chan);
+ if (config) {
+ gboolean tmp;
+
+ tmp = g_key_file_get_boolean(config, "General", "ForceMaster",
+ &err);
+ if (err) {
+ debug("audio.conf: %s", err->message);
+ g_error_free(err);
+ err = NULL;
+ } else
+ master = tmp;
+
+ tmp = g_key_file_get_boolean(config, "Headset", "DisableHFP",
+ &err);
+ if (err) {
+ debug("audio.conf: %s", err->message);
+ g_error_free(err);
+ err = NULL;
+ } else
+ hfp = tmp;
+ }
+
+ hs_server = server_socket(&chan, master);
if (!hs_server)
return -1;
@@ -1568,22 +1594,12 @@ static int headset_server_init(DBusConnection *conn, GKeyFile *config)
g_io_add_watch(hs_server, G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
(GIOFunc) ag_io_cb, NULL);
- if (config) {
- hfp = g_key_file_get_boolean(config, "Headset", "EnableHFP",
- &err);
- if (err) {
- debug("audio.conf: %s", err->message);
- g_error_free(err);
- err = NULL;
- }
- }
-
if (!hfp)
return 0;
chan = DEFAULT_HF_AG_CHANNEL;
- hf_server = server_socket(&chan);
+ hf_server = server_socket(&chan, master);
if (!hf_server)
return -1;
@@ -1697,7 +1713,7 @@ int audio_init(DBusConnection *conn, GKeyFile *config)
goto failed;
}
- if (enabled.control && avrcp_init(conn) < 0)
+ if (enabled.control && avrcp_init(conn, config) < 0)
goto failed;
if (!dbus_connection_register_interface(conn, AUDIO_MANAGER_PATH,