This patch rejects the SCO incoming connection if there isn't a service
level connection associated with the Bluetooth address pair.
---
 plugins/hfp_hf_bluez5.c | 50 ++++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 45 insertions(+), 5 deletions(-)

diff --git a/plugins/hfp_hf_bluez5.c b/plugins/hfp_hf_bluez5.c
index 49a84c5..28c57c3 100644
--- a/plugins/hfp_hf_bluez5.c
+++ b/plugins/hfp_hf_bluez5.c
@@ -63,11 +63,34 @@ struct hfp {
        DBusMessage *msg;
 };
 
+struct address_pair {
+       char local[18];
+       char remote[18];
+};
+
 static GHashTable *modem_hash = NULL;
 static GHashTable *devices_proxies = NULL;
 static GDBusClient *bluez = NULL;
 static guint sco_watch = 0;
 
+static gboolean modem_cmp(gpointer key, gpointer value,
+                                               gpointer user_data)
+{
+       const struct address_pair *pair = user_data;
+       struct ofono_modem *modem = value;
+       const char *local, *remote;
+       int ret;
+
+       local = ofono_modem_get_string(modem, "Local");
+       remote = ofono_modem_get_string(modem, "Remote");
+
+       ret = g_strcmp0(pair->remote, remote);
+       if (ret != 0)
+               return FALSE;
+
+       return g_strcmp0(pair->local, local) == 0;
+}
+
 static void hfp_debug(const char *str, void *user_data)
 {
        const char *prefix = user_data;
@@ -407,7 +430,9 @@ static const GDBusMethodTable profile_methods[] = {
 static gboolean sco_accept(GIOChannel *io, GIOCondition cond,
                                                        gpointer user_data)
 {
-       struct sockaddr_sco saddr;
+       struct ofono_modem *modem;
+       struct sockaddr_sco laddr, raddr;
+       struct address_pair pair;
        socklen_t alen;
        int sk, nsk;
 
@@ -416,14 +441,29 @@ static gboolean sco_accept(GIOChannel *io, GIOCondition 
cond,
 
        sk = g_io_channel_unix_get_fd(io);
 
-       memset(&saddr, 0, sizeof(saddr));
-       alen = sizeof(saddr);
+       memset(&raddr, 0, sizeof(raddr));
+       alen = sizeof(raddr);
 
-       nsk = accept(sk, (struct sockaddr *) &saddr, &alen);
+       nsk = accept(sk, (struct sockaddr *) &raddr, &alen);
        if (nsk < 0)
                return TRUE;
 
-       /* TODO: Verify if the device has a modem */
+       memset(&laddr, 0, sizeof(laddr));
+       alen = sizeof(laddr);
+       if (getsockname(nsk, (struct sockaddr *) &laddr, &alen) < 0) {
+               close(nsk);
+               return TRUE;
+       }
+
+       bt_ba2str(&laddr.sco_bdaddr, pair.local);
+       bt_ba2str(&raddr.sco_bdaddr, pair.remote);
+
+       modem = g_hash_table_find(modem_hash, modem_cmp, &pair);
+       if (modem == NULL) {
+               ofono_error("Rejecting SCO: SLC connection missing!");
+               close(nsk);
+               return TRUE;
+       }
 
        return TRUE;
 }
-- 
1.7.11.7

_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono

Reply via email to