This patch rejects the SCO incoming connection if there isn't a modem
(service level connection) associated with the address.
---
 plugins/hfp_hf_bluez5.c | 82 ++++++++++++++++++++++++++++++++++++++++---------
 1 file changed, 68 insertions(+), 14 deletions(-)

diff --git a/plugins/hfp_hf_bluez5.c b/plugins/hfp_hf_bluez5.c
index 87ae5e3..871c720 100644
--- a/plugins/hfp_hf_bluez5.c
+++ b/plugins/hfp_hf_bluez5.c
@@ -61,6 +61,13 @@
 struct hfp {
        struct hfp_slc_info info;
        DBusMessage *msg;
+       bdaddr_t src;
+       bdaddr_t dst;
+};
+
+struct sock_bdaddr {
+       bdaddr_t src;
+       bdaddr_t dst;
 };
 
 static GHashTable *modem_hash = NULL;
@@ -68,6 +75,21 @@ static GHashTable *devices_proxies = NULL;
 static GDBusClient *bluez = NULL;
 static guint sco_watch = 0;
 
+static gboolean modem_bacmp(gpointer key, gpointer value,
+                                               gpointer user_data)
+{
+       const struct sock_bdaddr *bda = user_data;
+       struct ofono_modem *modem = value;
+       struct hfp *hfp = ofono_modem_get_data(modem);
+       int ret;
+
+       ret = bt_bacmp(&bda->dst, &hfp->dst);
+       if (ret != 0)
+               return FALSE;
+
+       return bt_bacmp(&bda->src, &hfp->src) != 0 ? FALSE : TRUE;
+}
+
 static void hfp_debug(const char *str, void *user_data)
 {
        const char *prefix = user_data;
@@ -275,14 +297,15 @@ static DBusMessage *profile_new_connection(DBusConnection 
*conn,
 {
        struct hfp *hfp;
        struct ofono_modem *modem;
+       struct sockaddr_rc src, dst;
+       socklen_t alen;
        DBusMessageIter iter;
        GDBusProxy *proxy;
        DBusMessageIter entry;
-       const char *device, *alias, *address;
+       const char *device, *alias;
+       char device_address[18];
        int fd, err;
 
-       DBG("Profile handler NewConnection");
-
        if (dbus_message_iter_init(msg, &entry) == FALSE)
                goto invalid;
 
@@ -301,11 +324,6 @@ static DBusMessage *profile_new_connection(DBusConnection 
*conn,
 
        dbus_message_iter_get_basic(&iter, &alias);
 
-       if (g_dbus_proxy_get_property(proxy, "Address", &iter) == FALSE)
-               goto invalid;
-
-       dbus_message_iter_get_basic(&iter, &address);
-
        dbus_message_iter_next(&entry);
        if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_UNIX_FD)
                goto invalid;
@@ -314,7 +332,24 @@ static DBusMessage *profile_new_connection(DBusConnection 
*conn,
        if (fd < 0)
                goto invalid;
 
-       modem = modem_register(device, address, alias);
+       memset(&src, 0, sizeof(src));
+       alen = sizeof(src);
+       if (getsockname(fd, (struct sockaddr *) &src, &alen) < 0) {
+               close(fd);
+               goto invalid;
+       }
+
+       memset(&dst, 0, sizeof(dst));
+       alen = sizeof(dst);
+       if (getpeername(fd, (struct sockaddr *) &dst, &alen) < 0) {
+               close(fd);
+               goto invalid;
+       }
+
+       bt_ba2str(&dst.rc_bdaddr, device_address);
+       DBG("Profile handler NewConnection: %s", device_address);
+
+       modem = modem_register(device, device_address, alias);
        if (modem == NULL) {
                close(fd);
                return g_dbus_create_error(msg, BLUEZ_ERROR_INTERFACE
@@ -329,6 +364,8 @@ static DBusMessage *profile_new_connection(DBusConnection 
*conn,
                                        "Not enough resources");
 
        hfp = ofono_modem_get_data(modem);
+       bt_bacpy(&hfp->src, &src.rc_bdaddr);
+       bt_bacpy(&hfp->dst, &dst.rc_bdaddr);
        hfp->msg = dbus_message_ref(msg);
 
        return NULL;
@@ -384,7 +421,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 src, dst;
+       struct sock_bdaddr bda;
        socklen_t alen;
        int sk, nsk;
 
@@ -393,14 +432,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(&dst, 0, sizeof(dst));
+       alen = sizeof(dst);
 
-       nsk = accept(sk, (struct sockaddr *) &saddr, &alen);
+       nsk = accept(sk, (struct sockaddr *) &dst, &alen);
        if (nsk < 0)
                return TRUE;
 
-       /* TODO: Verify if the device has a modem */
+       memset(&src, 0, sizeof(src));
+       alen = sizeof(src);
+       if (getsockname(nsk, (struct sockaddr *) &src, &alen) < 0) {
+               close(nsk);
+               return TRUE;
+       }
+
+       bt_bacpy(&bda.src, &src.sco_bdaddr);
+       bt_bacpy(&bda.dst, &dst.sco_bdaddr);
+
+       modem = g_hash_table_find(modem_hash, modem_bacmp, &bda);
+       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