This patch allows oFono HFP plugin to handle HFP connections before
the Bluetooth device creation procedure finishes.
---
plugins/bluetooth.c | 26 +++++++++++++++++
plugins/bluetooth.h | 2 ++
plugins/hfp_hf.c | 84 +++++++++++++++++++++++++++++++++++------------------
3 files changed, 83 insertions(+), 29 deletions(-)
diff --git a/plugins/bluetooth.c b/plugins/bluetooth.c
index 92e11f0..3e63a3d 100644
--- a/plugins/bluetooth.c
+++ b/plugins/bluetooth.c
@@ -31,6 +31,8 @@
#include <unistd.h>
#include <glib.h>
#include <gdbus.h>
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/rfcomm.h>
#define OFONO_API_SUBJECT_TO_CHANGE
#include <ofono/plugin.h>
@@ -1148,5 +1150,29 @@ void bluetooth_unregister_server(struct server *server)
bluetooth_unref();
}
+int bluetooth_get_address(int fd, char *adapter_address, char *device_address)
+{
+ struct sockaddr_rc saddr;
+ socklen_t alen;
+
+ alen = sizeof(saddr);
+
+ if (adapter_address) {
+ if (getsockname(fd, (struct sockaddr *)&saddr, &alen) < 0)
+ return -errno;
+
+ ba2str(&saddr.rc_bdaddr, adapter_address);
+ }
+
+ if (device_address) {
+ if (getpeername(fd, (struct sockaddr *)&saddr, &alen) < 0)
+ return -errno;
+
+ ba2str(&saddr.rc_bdaddr, device_address);
+ }
+
+ return 0;
+}
+
OFONO_PLUGIN_DEFINE(bluetooth, "Bluetooth Utils Plugins", VERSION,
OFONO_PLUGIN_PRIORITY_DEFAULT, NULL, NULL)
diff --git a/plugins/bluetooth.h b/plugins/bluetooth.h
index a3937ac..10db23d 100644
--- a/plugins/bluetooth.h
+++ b/plugins/bluetooth.h
@@ -90,3 +90,5 @@ void bluetooth_parse_properties(DBusMessageIter *array,
int bluetooth_sap_client_register(struct bluetooth_sap_driver *sap,
struct ofono_modem *modem);
void bluetooth_sap_client_unregister(struct ofono_modem *modem);
+
+int bluetooth_get_address(int fd, char *adapter_address, char *device_address);
diff --git a/plugins/hfp_hf.c b/plugins/hfp_hf.c
index 22514da..9c07a1d 100644
--- a/plugins/hfp_hf.c
+++ b/plugins/hfp_hf.c
@@ -79,6 +79,40 @@ static void hfp_data_free(gpointer user_data)
g_free(hfp_data);
}
+static struct hfp_data *hfp_data_new(const gchar *adapter_addr,
+ const gchar *device_addr,
+ const gchar *device_path,
+ const gchar *alias)
+{
+ struct hfp_data *hfp_data;
+
+ hfp_data = g_try_new0(struct hfp_data, 1);
+ if (hfp_data == NULL)
+ return NULL;
+
+ hfp_data->adapter_address = g_strdup(adapter_addr);
+ if (hfp_data->adapter_address == NULL)
+ goto free;
+
+ hfp_data->device_address = g_strdup(device_addr);
+ if (hfp_data->device_address == NULL)
+ goto free;
+
+ hfp_data->device_path = g_strdup(device_path);
+ if (hfp_data->device_path == NULL)
+ goto free;
+
+ hfp_data->device_alias = g_strdup(alias);
+ if (hfp_data->device_alias == NULL)
+ goto free;
+
+ return hfp_data;
+
+free:
+ hfp_data_free(hfp_data);
+ return NULL;
+}
+
static void parse_guint16(DBusMessageIter *iter, gpointer user_data)
{
guint16 *value = user_data;
@@ -222,34 +256,13 @@ static int hfp_hf_probe(const char *device, const char
*dev_addr,
ofono_info("Using device: %s, devaddr: %s, adapter: %s",
device, dev_addr, adapter_addr);
- hfp_data = g_try_new0(struct hfp_data, 1);
+ hfp_data = hfp_data_new(adapter_addr, dev_addr, device, alias);
if (hfp_data == NULL)
- goto free;
-
- hfp_data->adapter_address = g_strdup(adapter_addr);
- if (hfp_data->adapter_address == NULL)
- goto free;
-
- hfp_data->device_address = g_strdup(dev_addr);
- if (hfp_data->device_address == NULL)
- goto free;
-
- hfp_data->device_path = g_strdup(device);
- if (hfp_data->device_path == NULL)
- goto free;
-
- hfp_data->device_alias = g_strdup(alias);
- if (hfp_data->device_alias == NULL)
- goto free;
+ return -ENOMEM;
g_hash_table_insert(hfp_hash, g_strdup(device), hfp_data);
return 0;
-
-free:
- hfp_data_free(hfp_data);
-
- return -ENOMEM;
}
static gboolean hfp_remove_modem(gpointer key, gpointer value,
@@ -315,12 +328,6 @@ static DBusMessage *profile_new_connection(DBusConnection
*conn,
goto error;
dbus_message_iter_get_basic(&entry, &device);
- hfp_data = g_hash_table_lookup(hfp_hash, device);
- if (hfp_data == NULL) {
- DBG("%s: doesn't support HFP", device);
- goto error;
- }
-
dbus_message_iter_next(&entry);
if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_UNIX_FD)
goto error;
@@ -336,6 +343,25 @@ static DBusMessage *profile_new_connection(DBusConnection
*conn,
"Features", parse_guint16, &features,
NULL);
+ hfp_data = g_hash_table_lookup(hfp_hash, device);
+ if (hfp_data == NULL) {
+ char adapter_address[18], device_address[18];
+
+ /*
+ * Incoming connection notification can arrive before
+ * the Bluetooth device creation finishes.
+ */
+ if (bluetooth_get_address(fd, adapter_address,
+ device_address) < 0)
+ return g_dbus_create_error(msg,
+ BLUEZ_ERROR_INTERFACE ".Rejected",
+ "Invalid arguments in method call");
+
+ hfp_data = hfp_data_new(adapter_address, device_address,
+ device, device_address);
+ g_hash_table_insert(hfp_hash, g_strdup(device), hfp_data);
+ }
+
DBG("hfp_data: %p SLC FD: %d Version: 0x%04x Features: 0x%04x",
hfp_data, fd, version, features);
--
1.7.11.7
_______________________________________________
ofono mailing list
[email protected]
http://lists.ofono.org/listinfo/ofono