Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ v5 11/14] core: Disable unnecessary auto connections
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Paulo Alcantara
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

From: Paulo Alcantara <paulo.alcantara@openbossa.org>

BlueZ host disconnects the link when encryption fails. ECONNABORTED
error is returned by the kernel when the connection is terminated by the
local host. This scenario commonly happens when authentication fails due
PIN or Key Missing.
---
 src/device.c | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/device.c b/src/device.c
index 92bf4ae..f9a0f3c 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1945,6 +1945,9 @@ static void att_error_cb(const GError *gerr, gpointer user_data)
 	struct att_callbacks *attcb = user_data;
 	struct btd_device *device = attcb->user_data;
 
+	if (g_error_matches(gerr, BT_IO_ERROR, ECONNABORTED))
+		return;
+
 	if (device->auto_connect == FALSE)
 		return;
 
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 10/14] core: Queue discovery if scanning is active
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

This patch manages BR/EDR inquiry and BLE scanning discovery sessions.
A scanning session is added in the discovery session list when there is
a bonded device which requires re-connection.

bluetoothd decides if interleaved or scanning needs to be executed based
on the queued discovery sessions. Interleaved discovery has higher
priority, scanning only is executed when there is only a scanning
session active.
---
 src/adapter.c | 67 +++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 47 insertions(+), 20 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 70fbc02..8df97eb 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -133,6 +133,7 @@ struct btd_adapter {
 	GSList *devices;		/* Devices structure pointers */
 	GSList *mode_sessions;		/* Request Mode sessions */
 	GSList *disc_sessions;		/* Discovery sessions */
+	struct session_req *scanning_session;
 	GSList *connect_list;		/* Devices to connect when found */
 	guint discov_id;		/* Discovery timer */
 	gboolean discovering;		/* Discovery active */
@@ -222,18 +223,19 @@ static struct session_req *create_session(struct btd_adapter *adapter,
 					DBusConnection *conn, DBusMessage *msg,
 					uint8_t mode, GDBusWatchFunction cb)
 {
-	const char *sender = dbus_message_get_sender(msg);
+	const char *sender;
 	struct session_req *req;
 
 	req = g_new0(struct session_req, 1);
 	req->adapter = adapter;
-	req->conn = dbus_connection_ref(conn);
-	req->msg = dbus_message_ref(msg);
 	req->mode = mode;
 
-	if (cb == NULL)
+	if (conn == NULL || cb == NULL || msg == NULL)
 		return session_ref(req);
 
+	req->conn = dbus_connection_ref(conn);
+	req->msg = dbus_message_ref(msg);
+	sender = dbus_message_get_sender(msg);
 	req->owner = g_strdup(sender);
 	req->id = g_dbus_add_disconnect_watch(conn, sender, cb, req, NULL);
 
@@ -445,7 +447,9 @@ static struct session_req *find_session(GSList *list, const char *sender)
 	for (; list; list = list->next) {
 		struct session_req *req = list->data;
 
-		if (g_str_equal(req->owner, sender))
+		/* req->owner may be NULL if the session has been added by the
+		 * daemon itself, so we use g_strcmp0 instead of g_str_equal */
+		if (g_strcmp0(req->owner, sender) == 0)
 			return req;
 	}
 
@@ -520,7 +524,7 @@ static void session_remove(struct session_req *req)
 	struct btd_adapter *adapter = req->adapter;
 
 	/* Ignore set_mode session */
-	if (req->owner == NULL)
+	if (req->owner == NULL && adapter->pending_mode)
 		return;
 
 	DBG("%s session %p with %s deactivated",
@@ -1009,7 +1013,12 @@ static gboolean discovery_cb(gpointer user_data)
 	struct btd_adapter *adapter = user_data;
 
 	adapter->discov_id = 0;
-	mgmt_start_discovery(adapter->dev_id);
+
+	if (adapter->scanning_session &&
+			(g_slist_length(adapter->disc_sessions) == 1))
+		mgmt_start_scanning(adapter->dev_id);
+	else
+		mgmt_start_discovery(adapter->dev_id);
 
 	return FALSE;
 }
@@ -2205,6 +2214,8 @@ const char *btd_adapter_get_name(struct btd_adapter *adapter)
 void adapter_connect_list_add(struct btd_adapter *adapter,
 					struct btd_device *device)
 {
+	struct session_req *req;
+
 	if (g_slist_find(adapter->connect_list, device)) {
 		DBG("ignoring already added device %s",
 						device_get_path(device));
@@ -2216,10 +2227,21 @@ void adapter_connect_list_add(struct btd_adapter *adapter,
 	DBG("%s added to %s's connect_list", device_get_path(device),
 								adapter->name);
 
-	if (adapter->disc_sessions)
+	if (!adapter->up)
+		return;
+
+	if (adapter->off_requested)
+		return;
+
+	if (adapter->scanning_session)
 		return;
 
-	mgmt_start_scanning(adapter->dev_id);
+	if (adapter->disc_sessions == NULL)
+		adapter->discov_id = g_idle_add(discovery_cb, adapter);
+
+	req = create_session(adapter, NULL, NULL, 0, NULL);
+	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
+	adapter->scanning_session = req;
 }
 
 void adapter_connect_list_remove(struct btd_adapter *adapter,
@@ -2239,6 +2261,7 @@ void adapter_connect_list_remove(struct btd_adapter *adapter,
 
 void btd_adapter_start(struct btd_adapter *adapter)
 {
+	struct session_req *req;
 	char address[18];
 	gboolean powered;
 
@@ -2265,8 +2288,15 @@ void btd_adapter_start(struct btd_adapter *adapter)
 
 	info("Adapter %s has been enabled", adapter->path);
 
-	if (g_slist_length(adapter->connect_list))
-		mgmt_start_scanning(adapter->dev_id);
+	if (g_slist_length(adapter->connect_list) == 0 ||
+					adapter->disc_sessions)
+		return;
+
+	req = create_session(adapter, NULL, NULL, 0, NULL);
+	adapter->disc_sessions = g_slist_append(adapter->disc_sessions, req);
+	adapter->scanning_session = req;
+
+	adapter->discov_id = g_idle_add(discovery_cb, adapter);
 }
 
 static void reply_pending_requests(struct btd_adapter *adapter)
@@ -2610,6 +2640,11 @@ void adapter_set_discovering(struct btd_adapter *adapter,
 
 	connect_list_size = g_slist_length(adapter->connect_list);
 
+	if (connect_list_size == 0 && adapter->scanning_session) {
+		session_unref(adapter->scanning_session);
+		adapter->scanning_session = NULL;
+	}
+
 	if (adapter_has_discov_sessions(adapter)) {
 		adapter->discov_id = g_idle_add(discovery_cb, adapter);
 
@@ -2618,14 +2653,6 @@ void adapter_set_discovering(struct btd_adapter *adapter,
 				g_slist_length(adapter->disc_sessions));
 		return;
 	}
-
-	if (connect_list_size) {
-		mgmt_start_scanning(adapter->dev_id);
-
-		DBG("hci%u restarting scanning connect_list size %u",
-				adapter->dev_id, connect_list_size);
-		return;
-	}
 }
 
 static void suspend_discovery(struct btd_adapter *adapter)
@@ -2940,7 +2967,7 @@ static gboolean clean_connecting_state(GIOChannel *io, GIOCondition cond, gpoint
 
 	if (adapter->waiting_to_connect == 0 &&
 					g_slist_length(adapter->connect_list))
-		mgmt_start_scanning(adapter->dev_id);
+		adapter->discov_id = g_idle_add(discovery_cb, adapter);
 
 	btd_device_unref(device);
 	return FALSE;
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 09/14] core: Start LE scanning when a device requests
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

This patch enables the LE scanning when a device requires connection and
there isn't discovery sessions, triggering the General Connection
Establishment Procedure.
---
 src/adapter.c | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/adapter.c b/src/adapter.c
index 0355a4c..70fbc02 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2215,6 +2215,11 @@ void adapter_connect_list_add(struct btd_adapter *adapter,
 						btd_device_ref(device));
 	DBG("%s added to %s's connect_list", device_get_path(device),
 								adapter->name);
+
+	if (adapter->disc_sessions)
+		return;
+
+	mgmt_start_scanning(adapter->dev_id);
 }
 
 void adapter_connect_list_remove(struct btd_adapter *adapter,
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 08/14] core: Replace interleaved by LE scanning
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

This patches replaces the interleaved discovery by LE scanning when LE
re-connection is required.
---
 src/adapter.c | 22 +++++++++++++++-------
 1 file changed, 15 insertions(+), 7 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index e1c4fe3..0355a4c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2261,7 +2261,7 @@ void btd_adapter_start(struct btd_adapter *adapter)
 	info("Adapter %s has been enabled", adapter->path);
 
 	if (g_slist_length(adapter->connect_list))
-		mgmt_start_discovery(adapter->dev_id);
+		mgmt_start_scanning(adapter->dev_id);
 }
 
 static void reply_pending_requests(struct btd_adapter *adapter)
@@ -2605,14 +2605,22 @@ void adapter_set_discovering(struct btd_adapter *adapter,
 
 	connect_list_size = g_slist_length(adapter->connect_list);
 
-	if (!adapter_has_discov_sessions(adapter) && !connect_list_size)
+	if (adapter_has_discov_sessions(adapter)) {
+		adapter->discov_id = g_idle_add(discovery_cb, adapter);
+
+		DBG("hci%u restarting discovery: disc_sessions %u",
+				adapter->dev_id,
+				g_slist_length(adapter->disc_sessions));
 		return;
+	}
 
-	DBG("hci%u restarting discovery: disc_sessions %u, connect_list size "
-		"%u", adapter->dev_id, g_slist_length(adapter->disc_sessions),
-							connect_list_size);
+	if (connect_list_size) {
+		mgmt_start_scanning(adapter->dev_id);
 
-	adapter->discov_id = g_idle_add(discovery_cb, adapter);
+		DBG("hci%u restarting scanning connect_list size %u",
+				adapter->dev_id, connect_list_size);
+		return;
+	}
 }
 
 static void suspend_discovery(struct btd_adapter *adapter)
@@ -2927,7 +2935,7 @@ static gboolean clean_connecting_state(GIOChannel *io, GIOCondition cond, gpoint
 
 	if (adapter->waiting_to_connect == 0 &&
 					g_slist_length(adapter->connect_list))
-		mgmt_start_discovery(adapter->dev_id);
+		mgmt_start_scanning(adapter->dev_id);
 
 	btd_device_unref(device);
 	return FALSE;
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 07/14] mgmt: Add LE scanning callback
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

This patch adds a new callback to allow the adapter to control LE
scanning. The current approach uses the active scanning with default
windows and intervals defined by the core spec without any filtering.
---
 src/mgmt.c | 34 ++++++++++++++++++++++++++++++++++
 src/mgmt.h |  1 +
 2 files changed, 35 insertions(+)

diff --git a/src/mgmt.c b/src/mgmt.c
index 4643816..8e69778 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -2043,6 +2043,40 @@ int mgmt_start_discovery(int index)
 	return 0;
 }
 
+int mgmt_start_scanning(int index)
+{
+	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
+	struct mgmt_hdr *hdr = (void *) buf;
+	struct mgmt_cp_start_discovery *cp = (void *) &buf[sizeof(*hdr)];
+	struct controller_info *info = &controllers[index];
+
+	DBG("index %d", index);
+
+	if (!mgmt_low_energy(info->current_settings)) {
+		error("scanning failed: Low Energy not enabled/supported");
+		return -ENOTSUP;
+	}
+
+	info->discov_type = 0;
+	hci_set_bit(BDADDR_LE_PUBLIC, &info->discov_type);
+	hci_set_bit(BDADDR_LE_RANDOM, &info->discov_type);
+
+	memset(buf, 0, sizeof(buf));
+	hdr->opcode = htobs(MGMT_OP_START_DISCOVERY);
+	hdr->len = htobs(sizeof(*cp));
+	hdr->index = htobs(index);
+
+	cp->type = info->discov_type;
+
+	if (write(mgmt_sock, buf, sizeof(buf)) < 0) {
+		int err = -errno;
+		error("failed to write to MGMT socket: %s", strerror(-err));
+		return err;
+	}
+
+	return 0;
+}
+
 int mgmt_stop_discovery(int index)
 {
 	char buf[MGMT_HDR_SIZE + sizeof(struct mgmt_cp_start_discovery)];
diff --git a/src/mgmt.h b/src/mgmt.h
index 95245d2..eb7434a 100644
--- a/src/mgmt.h
+++ b/src/mgmt.h
@@ -33,6 +33,7 @@ int mgmt_set_dev_class(int index, uint8_t major, uint8_t minor);
 int mgmt_set_fast_connectable(int index, gboolean enable);
 
 int mgmt_start_discovery(int index);
+int mgmt_start_scanning(int index);
 int mgmt_stop_discovery(int index);
 
 int mgmt_read_clock(int index, bdaddr_t *bdaddr, int which, int timeout,
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 06/14] core: Mutually exclude concurrent connections
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

Since controllers don't support more than one ongoing connection
procedure at the same time, new connection attempts needs to yield if
there is an ongoing connection procedure already.
---
 src/adapter.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++--------
 src/device.c  |  6 +++---
 src/device.h  |  2 +-
 3 files changed, 57 insertions(+), 12 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 298a9cd..e1c4fe3 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -136,6 +136,8 @@ struct btd_adapter {
 	GSList *connect_list;		/* Devices to connect when found */
 	guint discov_id;		/* Discovery timer */
 	gboolean discovering;		/* Discovery active */
+	gboolean connecting;		/* Connect active */
+	guint waiting_to_connect;	/* # of devices waiting to connect */
 	gboolean discov_suspended;	/* Discovery suspended */
 	guint auto_timeout_id;		/* Automatic connections timeout */
 	sdp_list_t *services;		/* Services associated to adapter */
@@ -2257,6 +2259,9 @@ void btd_adapter_start(struct btd_adapter *adapter)
 	call_adapter_powered_callbacks(adapter, TRUE);
 
 	info("Adapter %s has been enabled", adapter->path);
+
+	if (g_slist_length(adapter->connect_list))
+		mgmt_start_discovery(adapter->dev_id);
 }
 
 static void reply_pending_requests(struct btd_adapter *adapter)
@@ -2580,6 +2585,7 @@ void adapter_set_discovering(struct btd_adapter *adapter,
 						gboolean discovering)
 {
 	const char *path = adapter->path;
+	guint connect_list_size;
 
 	adapter->discovering = discovering;
 
@@ -2594,11 +2600,17 @@ void adapter_set_discovering(struct btd_adapter *adapter,
 	g_slist_free_full(adapter->oor_devices, dev_info_free);
 	adapter->oor_devices = g_slist_copy(adapter->found_devices);
 
-	if (!adapter_has_discov_sessions(adapter) || adapter->discov_suspended)
+	if (adapter->discov_suspended)
+		return;
+
+	connect_list_size = g_slist_length(adapter->connect_list);
+
+	if (!adapter_has_discov_sessions(adapter) && !connect_list_size)
 		return;
 
-	DBG("hci%u restarting discovery, disc_sessions %u", adapter->dev_id,
-					g_slist_length(adapter->disc_sessions));
+	DBG("hci%u restarting discovery: disc_sessions %u, connect_list size "
+		"%u", adapter->dev_id, g_slist_length(adapter->disc_sessions),
+							connect_list_size);
 
 	adapter->discov_id = g_idle_add(discovery_cb, adapter);
 }
@@ -2906,18 +2918,44 @@ static char *read_stored_data(bdaddr_t *local, bdaddr_t *peer,
 	return textfile_get(filename, key);
 }
 
+static gboolean clean_connecting_state(GIOChannel *io, GIOCondition cond, gpointer user_data)
+{
+	struct btd_device *device = user_data;
+	struct btd_adapter *adapter = device_get_adapter(device);
+
+	adapter->connecting = FALSE;
+
+	if (adapter->waiting_to_connect == 0 &&
+					g_slist_length(adapter->connect_list))
+		mgmt_start_discovery(adapter->dev_id);
+
+	btd_device_unref(device);
+	return FALSE;
+}
+
 static gboolean connect_pending_cb(gpointer user_data)
 {
 	struct btd_device *device = user_data;
 	struct btd_adapter *adapter = device_get_adapter(device);
+	GIOChannel *io;
 
 	/* in the future we may want to check here if the controller supports
 	 * scanning and connecting at the same time */
 	if (adapter->discovering)
 		return TRUE;
 
-	device_att_connect(device);
+	if (adapter->connecting)
+		return TRUE;
+
+	adapter->connecting = TRUE;
+	adapter->waiting_to_connect--;
 
+	io = device_att_connect(device);
+	g_io_add_watch(io, G_IO_OUT | G_IO_ERR, clean_connecting_state,
+						btd_device_ref(device));
+	g_io_channel_unref(io);
+
+	btd_device_unref(device);
 	return FALSE;
 }
 
@@ -3009,12 +3047,19 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
 
 	if (bdaddr_type == BDADDR_LE_PUBLIC ||
 					bdaddr_type == BDADDR_LE_RANDOM) {
+		struct btd_device *device;
+
 		l = g_slist_find_custom(adapter->connect_list, bdaddr,
 					(GCompareFunc) device_bdaddr_cmp);
-		if (l) {
-			g_idle_add(connect_pending_cb, l->data);
-			stop_discovery(adapter);
-		}
+		if (!l)
+			goto done;
+
+		device = l->data;
+		adapter_connect_list_remove(adapter, device);
+
+		g_idle_add(connect_pending_cb,  btd_device_ref(device));
+		stop_discovery(adapter);
+		adapter->waiting_to_connect++;
 	}
 
 done:
diff --git a/src/device.c b/src/device.c
index cc8a77a..92bf4ae 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1963,7 +1963,7 @@ static void att_success_cb(gpointer user_data)
 	g_slist_foreach(device->attios, attio_connected, device->attrib);
 }
 
-gboolean device_att_connect(gpointer user_data)
+GIOChannel *device_att_connect(gpointer user_data)
 {
 	struct btd_device *device = user_data;
 	struct btd_adapter *adapter = device->adapter;
@@ -2006,12 +2006,12 @@ gboolean device_att_connect(gpointer user_data)
 		error("ATT bt_io_connect(%s): %s", addr, gerr->message);
 		g_error_free(gerr);
 		g_free(attcb);
-		return FALSE;
+		return NULL;
 	}
 
 	device->att_io = io;
 
-	return FALSE;
+	return g_io_channel_ref(io);
 }
 
 static void att_browse_error_cb(const GError *gerr, gpointer user_data)
diff --git a/src/device.h b/src/device.h
index ab70f90..1b5be4e 100644
--- a/src/device.h
+++ b/src/device.h
@@ -158,4 +158,4 @@ int device_unblock(DBusConnection *conn, struct btd_device *device,
 void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
 			uint16_t vendor_id, uint16_t product_id,
 			uint16_t product_ver);
-gboolean device_att_connect(gpointer user_data);
+GIOChannel *device_att_connect(gpointer user_data);
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 05/14] core: Use adapter connect list for LE connections
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

When a connection is needed for a LE device it is added to the adapter
connect list instead of directly connecting the ATT io channel.
---
 src/adapter.c |  2 +-
 src/device.c  | 45 +++++++++++----------------------------------
 src/device.h  |  1 +
 3 files changed, 13 insertions(+), 35 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index c17f518..298a9cd 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2916,7 +2916,7 @@ static gboolean connect_pending_cb(gpointer user_data)
 	if (adapter->discovering)
 		return TRUE;
 
-	/* TODO: call device connect callback */
+	device_att_connect(device);
 
 	return FALSE;
 }
diff --git a/src/device.c b/src/device.c
index c65f0b7..cc8a77a 100644
--- a/src/device.c
+++ b/src/device.c
@@ -68,8 +68,6 @@
 #define DISCONNECT_TIMER	2
 #define DISCOVERY_TIMER		2
 
-#define AUTO_CONNECTION_INTERVAL	5 /* Next connection attempt */
-
 struct btd_disconnect_data {
 	guint id;
 	disconnect_watch watch;
@@ -1831,15 +1829,6 @@ static void attio_disconnected(gpointer data, gpointer user_data)
 		attio->dcfunc(attio->user_data);
 }
 
-static void att_connect_dispatched(gpointer user_data)
-{
-	struct btd_device *device = user_data;
-
-	device->auto_id = 0;
-}
-
-static gboolean att_connect(gpointer user_data);
-
 static gboolean attrib_disconnected_cb(GIOChannel *io, GIOCondition cond,
 							gpointer user_data)
 {
@@ -1859,10 +1848,7 @@ static gboolean attrib_disconnected_cb(GIOChannel *io, GIOCondition cond,
 	if (device->auto_connect == FALSE || err != ETIMEDOUT)
 		goto done;
 
-	device->auto_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
-						AUTO_CONNECTION_INTERVAL,
-						att_connect, device,
-						att_connect_dispatched);
+	adapter_connect_list_add(device_get_adapter(device), device);
 
 done:
 	attio_cleanup(device);
@@ -1962,11 +1948,7 @@ static void att_error_cb(const GError *gerr, gpointer user_data)
 	if (device->auto_connect == FALSE)
 		return;
 
-	device->auto_id = g_timeout_add_seconds_full(G_PRIORITY_DEFAULT_IDLE,
-						AUTO_CONNECTION_INTERVAL,
-						att_connect, device,
-						att_connect_dispatched);
-
+	adapter_connect_list_add(device_get_adapter(device), device);
 	DBG("Enabling automatic connections");
 }
 
@@ -1981,7 +1963,7 @@ static void att_success_cb(gpointer user_data)
 	g_slist_foreach(device->attios, attio_connected, device->attrib);
 }
 
-static gboolean att_connect(gpointer user_data)
+gboolean device_att_connect(gpointer user_data)
 {
 	struct btd_device *device = user_data;
 	struct btd_adapter *adapter = device->adapter;
@@ -2243,6 +2225,9 @@ void device_set_temporary(struct btd_device *device, gboolean temporary)
 
 	DBG("temporary %d", temporary);
 
+	if (temporary)
+		adapter_connect_list_remove(device_get_adapter(device), device);
+
 	device->temporary = temporary;
 }
 
@@ -2258,6 +2243,7 @@ void device_set_bonded(struct btd_device *device, gboolean bonded)
 
 void device_set_auto_connect(struct btd_device *device, gboolean enable)
 {
+	struct btd_adapter *adapter = device_get_adapter(device);
 	char addr[18];
 
 	if (!device)
@@ -2271,15 +2257,10 @@ void device_set_auto_connect(struct btd_device *device, gboolean enable)
 
 	/* Disabling auto connect */
 	if (enable == FALSE) {
-		if (device->auto_id)
-			g_source_remove(device->auto_id);
+		adapter_connect_list_remove(adapter, device);
 		return;
 	}
 
-	/* Enabling auto connect */
-	if (device->auto_id != 0)
-		return;
-
 	if (device->attrib) {
 		DBG("Already connected");
 		return;
@@ -2288,9 +2269,8 @@ void device_set_auto_connect(struct btd_device *device, gboolean enable)
 	if (device->attios == NULL && device->attios_offline == NULL)
 		return;
 
-	device->auto_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
-						att_connect, device,
-						att_connect_dispatched);
+	/* Enabling auto connect */
+	adapter_connect_list_add(adapter, device);
 }
 
 static gboolean start_discovery(gpointer user_data)
@@ -3191,10 +3171,7 @@ guint btd_device_add_attio_callback(struct btd_device *device,
 
 	device->attios = g_slist_append(device->attios, attio);
 
-	if (device->auto_id == 0)
-		device->auto_id = g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
-						att_connect, device,
-						att_connect_dispatched);
+	adapter_connect_list_add(device_get_adapter(device), device);
 
 	return attio->id;
 }
diff --git a/src/device.h b/src/device.h
index f1d95c6..ab70f90 100644
--- a/src/device.h
+++ b/src/device.h
@@ -158,3 +158,4 @@ int device_unblock(DBusConnection *conn, struct btd_device *device,
 void device_set_pnpid(struct btd_device *device, uint8_t vendor_id_src,
 			uint16_t vendor_id, uint16_t product_id,
 			uint16_t product_ver);
+gboolean device_att_connect(gpointer user_data);
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 04/14] core: Add a list of LE devices to connect
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

This commit creates a per-adapter list of LE devices to connect when a
advertising from them is seen during a scan.
---
 src/adapter.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 src/adapter.h |  5 +++++
 2 files changed, 63 insertions(+), 1 deletion(-)

diff --git a/src/adapter.c b/src/adapter.c
index 771a956..c17f518 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -133,6 +133,7 @@ struct btd_adapter {
 	GSList *devices;		/* Devices structure pointers */
 	GSList *mode_sessions;		/* Request Mode sessions */
 	GSList *disc_sessions;		/* Discovery sessions */
+	GSList *connect_list;		/* Devices to connect when found */
 	guint discov_id;		/* Discovery timer */
 	gboolean discovering;		/* Discovery active */
 	gboolean discov_suspended;	/* Discovery suspended */
@@ -2199,6 +2200,36 @@ const char *btd_adapter_get_name(struct btd_adapter *adapter)
 	return adapter->name;
 }
 
+void adapter_connect_list_add(struct btd_adapter *adapter,
+					struct btd_device *device)
+{
+	if (g_slist_find(adapter->connect_list, device)) {
+		DBG("ignoring already added device %s",
+						device_get_path(device));
+		return;
+	}
+
+	adapter->connect_list = g_slist_append(adapter->connect_list,
+						btd_device_ref(device));
+	DBG("%s added to %s's connect_list", device_get_path(device),
+								adapter->name);
+}
+
+void adapter_connect_list_remove(struct btd_adapter *adapter,
+					struct btd_device *device)
+{
+	if (!g_slist_find(adapter->connect_list, device)) {
+		DBG("device %s is not on the list, ignoring",
+						device_get_path(device));
+		return;
+	}
+
+	adapter->connect_list = g_slist_remove(adapter->connect_list, device);
+	DBG("%s removed from %s's connect_list", device_get_path(device),
+								adapter->name);
+	btd_device_unref(device);
+}
+
 void btd_adapter_start(struct btd_adapter *adapter)
 {
 	char address[18];
@@ -2875,6 +2906,21 @@ static char *read_stored_data(bdaddr_t *local, bdaddr_t *peer,
 	return textfile_get(filename, key);
 }
 
+static gboolean connect_pending_cb(gpointer user_data)
+{
+	struct btd_device *device = user_data;
+	struct btd_adapter *adapter = device_get_adapter(device);
+
+	/* in the future we may want to check here if the controller supports
+	 * scanning and connecting at the same time */
+	if (adapter->discovering)
+		return TRUE;
+
+	/* TODO: call device connect callback */
+
+	return FALSE;
+}
+
 void adapter_update_found_devices(struct btd_adapter *adapter,
 					bdaddr_t *bdaddr, uint8_t bdaddr_type,
 					int8_t rssi, uint8_t confirm_name,
@@ -2886,6 +2932,7 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
 	gboolean legacy, name_known;
 	uint32_t dev_class;
 	int err;
+	GSList *l;
 
 	memset(&eir_data, 0, sizeof(eir_data));
 	err = eir_parse(&eir_data, data, data_len);
@@ -2908,7 +2955,7 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
 								eir_data.name);
 
 	dev = adapter_search_found_devices(adapter, bdaddr);
-	if (dev) {
+	if (dev && dev->bdaddr_type == BDADDR_BREDR) {
 		adapter->oor_devices = g_slist_remove(adapter->oor_devices,
 							dev);
 
@@ -2960,6 +3007,16 @@ void adapter_update_found_devices(struct btd_adapter *adapter,
 
 	adapter->found_devices = g_slist_prepend(adapter->found_devices, dev);
 
+	if (bdaddr_type == BDADDR_LE_PUBLIC ||
+					bdaddr_type == BDADDR_LE_RANDOM) {
+		l = g_slist_find_custom(adapter->connect_list, bdaddr,
+					(GCompareFunc) device_bdaddr_cmp);
+		if (l) {
+			g_idle_add(connect_pending_cb, l->data);
+			stop_discovery(adapter);
+		}
+	}
+
 done:
 	dev->rssi = rssi;
 
diff --git a/src/adapter.h b/src/adapter.h
index 5a0247e..cd37b15 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -232,3 +232,8 @@ int btd_adapter_gatt_server_start(struct btd_adapter *adapter);
 void btd_adapter_gatt_server_stop(struct btd_adapter *adapter);
 
 int btd_adapter_ssp_enabled(struct btd_adapter *adapter);
+
+void adapter_connect_list_add(struct btd_adapter *adapter,
+						struct btd_device *device);
+void adapter_connect_list_remove(struct btd_adapter *adapter,
+						struct btd_device *device);
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 03/14] core: Add compare function for bdaddr in a struct btd_device
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

This is a utility function similar to device_address_cmp but comparing
bdaddr instead of the string representing the address. This way is
possible to avoid allocating two buffers to temporarily hold the
strings, two sprintf() calls to generate the strings from the bdaddr
arrays, and a string comparison, substituting all of it for one memcmp()
call.
---
 src/device.c | 5 +++++
 src/device.h | 1 +
 2 files changed, 6 insertions(+)

diff --git a/src/device.c b/src/device.c
index d2bac97..c65f0b7 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1228,6 +1228,11 @@ gint device_address_cmp(struct btd_device *device, const gchar *address)
 	return strcasecmp(addr, address);
 }
 
+gint device_bdaddr_cmp(struct btd_device *device, bdaddr_t *bdaddr)
+{
+	return bacmp(&device->bdaddr, bdaddr);
+}
+
 static gboolean record_has_uuid(const sdp_record_t *rec,
 				const char *profile_uuid)
 {
diff --git a/src/device.h b/src/device.h
index edc64b9..f1d95c6 100644
--- a/src/device.h
+++ b/src/device.h
@@ -77,6 +77,7 @@ uint16_t btd_device_get_product(struct btd_device *device);
 uint16_t btd_device_get_version(struct btd_device *device);
 void device_remove(struct btd_device *device, gboolean remove_stored);
 gint device_address_cmp(struct btd_device *device, const gchar *address);
+gint device_bdaddr_cmp(struct btd_device *device, bdaddr_t *bdaddr);
 int device_browse_primary(struct btd_device *device, DBusConnection *conn,
 				DBusMessage *msg, gboolean secure);
 int device_browse_sdp(struct btd_device *device, DBusConnection *conn,
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 02/14] mgmt: Print error message when start_discovery fails
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

If we fail to communicate with the MGMT socket is better to print the
error message on the mgmtops plugin, where it really happened, instead
of leaving this job to its users.
---
 src/adapter.c | 6 +-----
 src/mgmt.c    | 7 +++++--
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index d4ba4fc..771a956 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -1004,13 +1004,9 @@ struct btd_device *adapter_get_device(DBusConnection *conn,
 static gboolean discovery_cb(gpointer user_data)
 {
 	struct btd_adapter *adapter = user_data;
-	int err;
 
 	adapter->discov_id = 0;
-
-	err = mgmt_start_discovery(adapter->dev_id);
-	if (err < 0)
-		error("start_discovery: %s (%d)", strerror(-err), -err);
+	mgmt_start_discovery(adapter->dev_id);
 
 	return FALSE;
 }
diff --git a/src/mgmt.c b/src/mgmt.c
index 0ec2912..4643816 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -2034,8 +2034,11 @@ int mgmt_start_discovery(int index)
 
 	cp->type = info->discov_type;
 
-	if (write(mgmt_sock, buf, sizeof(buf)) < 0)
-		return -errno;
+	if (write(mgmt_sock, buf, sizeof(buf)) < 0) {
+		int err = -errno;
+		error("failed to write to MGMT socket: %s", strerror(-err));
+		return err;
+	}
 
 	return 0;
 }
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 01/14] core: Control connections based on adapter state
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi
In-Reply-To: <1346785482-13359-1-git-send-email-jprvita@openbossa.org>

From: Claudio Takahasi <claudio.takahasi@openbossa.org>

This patch disable automatic ATTIO connections when the adapter is
powered down and enable automatic connection when the adapter is powered
on.
---
 src/adapter.c | 25 ++++++++++++++++---------
 1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index f507aa5..d4ba4fc 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2116,6 +2116,14 @@ static int get_pairable_timeout(const char *src)
 	return main_opts.pairto;
 }
 
+static void set_auto_connect(gpointer data, gpointer user_data)
+{
+	struct btd_device *device = data;
+	gboolean enable = GPOINTER_TO_INT(user_data);
+
+	device_set_auto_connect(device, enable);
+}
+
 static void call_adapter_powered_callbacks(struct btd_adapter *adapter,
 						gboolean powered)
 {
@@ -2125,7 +2133,10 @@ static void call_adapter_powered_callbacks(struct btd_adapter *adapter,
 		btd_adapter_powered_cb cb = l->data;
 
 		cb(adapter, powered);
-       }
+	}
+
+	g_slist_foreach(adapter->devices, set_auto_connect,
+						GINT_TO_POINTER(powered));
 }
 
 static void emit_device_disappeared(gpointer data, gpointer user_data)
@@ -3348,15 +3359,10 @@ static gboolean disable_auto(gpointer user_data)
 	return FALSE;
 }
 
-static void set_auto_connect(gpointer data, gpointer user_data)
-{
-	struct btd_device *device = data;
-
-	device_set_auto_connect(device, TRUE);
-}
-
 void btd_adapter_enable_auto_connect(struct btd_adapter *adapter)
 {
+	gboolean enable = TRUE;
+
 	if (!adapter->up)
 		return;
 
@@ -3365,7 +3371,8 @@ void btd_adapter_enable_auto_connect(struct btd_adapter *adapter)
 	if (adapter->auto_timeout_id)
 		return;
 
-	g_slist_foreach(adapter->devices, set_auto_connect, NULL);
+	g_slist_foreach(adapter->devices, set_auto_connect,
+						GINT_TO_POINTER(enable));
 
 	adapter->auto_timeout_id = g_timeout_add_seconds(main_opts.autoto,
 						disable_auto, adapter);
-- 
1.7.11.4


^ permalink raw reply related

* [PATCH BlueZ v5 00/14] LE General Connection Establishment procedure
From: João Paulo Rechi Vita @ 2012-09-04 19:04 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: João Paulo Rechi Vita

This series implement the LE General Connection Establishment procedure
for LE connections.

If there are LE bonded devices marked for auto connection they are added
to a connect_list on the adapter. When there is any device on this list
scan is performed continuously. When a device is found the connect_list
is checked. If that device is on the list scan is stopped and a
connection attempt is made to that device.

If any client tries to perform discovery and the scan for the General
Connection Establishment procedure is active, the discovery request is
queued and performed right after the GCEP scan session finishes.

This series changes quite a lot the LE connection logic, but we've been
testing and using this code at INdT for about 4 weeks. Any comments and
more testing are appreciated.

Claudio Takahasi (6):
  core: Control connections based on adapter state
  mgmt: Add LE scanning callback
  core: Replace interleaved by LE scanning
  core: Start LE scanning when a device requests
  core: Queue discovery if scanning is active
  core: Re-connect for ECONNRESET or ECONNABORTED

João Paulo Rechi Vita (7):
  mgmt: Print error message when start_discovery fails
  core: Add compare function for bdaddr in a struct btd_device
  core: Add a list of LE devices to connect
  core: Use adapter connect list for LE connections
  core: Mutually exclude concurrent connections
  mgmt: Add address type to bonding debug message
  core: Suspend scanning before connect on pairing

Paulo Alcantara (1):
  core: Disable unnecessary auto connections

 src/adapter.c | 193 ++++++++++++++++++++++++++++++++++++++++++++-------
 src/adapter.h |   5 ++
 src/device.c  | 217 +++++++++++++++++++++++++++++-----------------------------
 src/device.h  |   2 +
 src/mgmt.c    |  44 +++++++++++-
 src/mgmt.h    |   1 +
 6 files changed, 325 insertions(+), 137 deletions(-)

-- 
1.7.11.4


^ permalink raw reply

* Re: Bluetooth: Use GFP_KERNEL in read_index_list
From: Gustavo Padovan @ 2012-09-04 18:52 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: szymon.janc, linux-bluetooth
In-Reply-To: <20120904162137.GA11841@elgon.mountain>

Hi Dan,

* Dan Carpenter <dan.carpenter@oracle.com> [2012-09-04 19:21:37 +0300]:

> Hello Szymon Janc,
> 
> The patch 7cfeb868eb85: "Bluetooth: Use GFP_KERNEL in
> read_index_list" from Aug 31, 2012, leads to the following warning:
> net/bluetooth/mgmt.c:343 read_index_list()
> 	 error: scheduling with locks held:  'read_lock:hci_dev_list_lock'
> 
> This patch should be reverted because we're not allowed to schedule
> while holding the read lock.  The way to avoid these bugs in the future
> is to test with CONFIG_DEBUG_ATOMIC_SLEEP=y.  It will give a big splat.

I reverted this patch earlier this morning. It should be ok now.

	Gustavo

^ permalink raw reply

* re: Bluetooth: Use GFP_KERNEL in read_index_list
From: Dan Carpenter @ 2012-09-04 16:21 UTC (permalink / raw)
  To: szymon.janc; +Cc: linux-bluetooth

Hello Szymon Janc,

The patch 7cfeb868eb85: "Bluetooth: Use GFP_KERNEL in
read_index_list" from Aug 31, 2012, leads to the following warning:
net/bluetooth/mgmt.c:343 read_index_list()
	 error: scheduling with locks held:  'read_lock:hci_dev_list_lock'

This patch should be reverted because we're not allowed to schedule
while holding the read lock.  The way to avoid these bugs in the future
is to test with CONFIG_DEBUG_ATOMIC_SLEEP=y.  It will give a big splat.

regards,
dan carpenter


^ permalink raw reply

* Re: [RFC v4 15/18] Refactor bt_get_unaligned macro
From: Marcel Holtmann @ 2012-09-04 15:21 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth
In-Reply-To: <1346769697-9930-16-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

> Use extra parameter type for bt_get_unaligned to avoid pointer casting
> which might trigger compile time errors due to unaligned memory access.
> 
> ---
>  attrib/att.h       |    6 +++---
>  lib/bluetooth.h    |   28 ++++++++++++++--------------
>  lib/sdp.c          |   22 +++++++++++-----------
>  src/sdpd-request.c |    4 ++--
>  4 files changed, 30 insertions(+), 30 deletions(-)
> 
> diff --git a/attrib/att.h b/attrib/att.h
> index a563255..6101dac 100644
> --- a/attrib/att.h
> +++ b/attrib/att.h
> @@ -115,19 +115,19 @@ struct att_range {
>  static inline uint8_t att_get_u8(const void *ptr)
>  {
>  	const uint8_t *u8_ptr = ptr;
> -	return bt_get_unaligned(u8_ptr);
> +	return bt_get_unaligned(u8_ptr, uint8_t);
>  }
>  
>  static inline uint16_t att_get_u16(const void *ptr)
>  {
>  	const uint16_t *u16_ptr = ptr;
> -	return btohs(bt_get_unaligned(u16_ptr));
> +	return btohs(bt_get_unaligned(u16_ptr, uint16_t));
>  }
>  
>  static inline uint32_t att_get_u32(const void *ptr)
>  {
>  	const uint32_t *u32_ptr = ptr;
> -	return btohl(bt_get_unaligned(u32_ptr));
> +	return btohl(bt_get_unaligned(u32_ptr, uint32_t));
>  }
>  
>  static inline uint128_t att_get_u128(const void *ptr)
> diff --git a/lib/bluetooth.h b/lib/bluetooth.h
> index 161b7bd..898a122 100644
> --- a/lib/bluetooth.h
> +++ b/lib/bluetooth.h
> @@ -137,10 +137,10 @@ enum {
>  #endif
>  
>  /* Bluetooth unaligned access */
> -#define bt_get_unaligned(ptr)			\
> +#define bt_get_unaligned(ptr, type)		\
>  ({						\
>  	struct __attribute__((packed)) {	\
> -		typeof(*(ptr)) __v;		\
> +		type __v;			\
>  	} *__p = (typeof(__p)) (ptr);		\
>  	__p->__v;				\
>  })

I am not in favor of this change at all. We should not need such a
change. And in addition, it break the API.

Regards

Marcel



^ permalink raw reply

* [RFC v4 18/18] sdp: Fix build error due to unaligned memory access
From: Szymon Janc @ 2012-09-04 14:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1346769697-9930-1-git-send-email-szymon.janc@tieto.com>

This fix following compilation errors on ARM.

  CC     lib/sdp.lo
lib/sdp.c: In function 'sdp_process':
lib/sdp.c:4149:22: error: cast increases required alignment of target type [-Wer
ror=cast-align]
cc1: all warnings being treated as errors
make[1]: *** [lib/sdp.lo] Error 1
make: *** [all] Error 2

---
 lib/sdp.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/lib/sdp.c b/lib/sdp.c
index a533b12..ee51eca 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -4146,14 +4146,16 @@ int sdp_process(sdp_session_t *session)
 			rsp_count = sizeof(tsrc) + sizeof(csrc) + csrc * 4;
 		} else {
 			/* point to the first csrc */
-			uint16_t *pcsrc = (uint16_t *) (t->rsp_concat_buf.data + 2);
+			uint8_t *pcsrc = t->rsp_concat_buf.data + 2;
+			uint16_t tcsrc = bt_get_unaligned(pcsrc, uint16_t);
 
 			/* FIXME: update the interface later. csrc doesn't need be passed to clients */
 
 			pdata += sizeof(uint16_t); /* point to csrc */
 
 			/* the first csrc contains the sum of partial csrc responses */
-			*pcsrc += bt_get_unaligned(pdata, uint16_t);
+			tcsrc += bt_get_unaligned(pdata, uint16_t);
+			memcpy(pcsrc, &tcsrc, sizeof(tcsrc));
 
 			pdata += sizeof(uint16_t); /* point to the first handle */
 			rsp_count = csrc * 4;
-- 
1.7.9.5


^ permalink raw reply related

* [RFC v4 17/18] monitor: Fix compilation errors due to unaligned memory access
From: Szymon Janc @ 2012-09-04 14:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1346769697-9930-1-git-send-email-szymon.janc@tieto.com>

This fix following compilation errors on ARM.

  CC     monitor/hcidump.o
monitor/hcidump.c: In function device_callback:
monitor/hcidump.c:147:11: error: cast increases required alignment of
	target type [-Werror=cast-align]
monitor/hcidump.c:150:10: error: cast increases required alignment of
	target type [-Werror=cast-align]
monitor/hcidump.c: In function stack_internal_callback:
monitor/hcidump.c:348:9: error: cast increases required alignment of
	target type [-Werror=cast-align]
cc1: all warnings being treated as errors
make[1]: *** [monitor/hcidump.o] Error 1
make: *** [all] Error 2

  CC     monitor/hcidump.o
monitor/hcidump.c: In function stack_internal_callback:
monitor/hcidump.c:357:9: error: cast increases required alignment of
	target type [-Werror=cast-align]
cc1: all warnings being treated as errors
make[1]: *** [monitor/hcidump.o] Error 1
make: *** [all] Error 2

  CC     monitor/control.o
monitor/control.c: In function data_callback:
monitor/control.c:574:10: error: cast increases required alignment of
	target type [-Werror=cast-align]
cc1: all warnings being treated as errors
make[1]: *** [monitor/control.o] Error 1
make: *** [all] Error 2

---
 monitor/control.c |    7 +++++--
 monitor/hcidump.c |   21 ++++++++++++++-------
 2 files changed, 19 insertions(+), 9 deletions(-)

diff --git a/monitor/control.c b/monitor/control.c
index c300ae9..c5ff26b 100644
--- a/monitor/control.c
+++ b/monitor/control.c
@@ -555,6 +555,7 @@ static void data_callback(int fd, uint32_t events, void *user_data)
 	while (1) {
 		struct cmsghdr *cmsg;
 		struct timeval *tv = NULL;
+		struct timeval ctv;
 		uint16_t opcode, index, pktlen;
 		ssize_t len;
 
@@ -570,8 +571,10 @@ static void data_callback(int fd, uint32_t events, void *user_data)
 			if (cmsg->cmsg_level != SOL_SOCKET)
 				continue;
 
-			if (cmsg->cmsg_type == SCM_TIMESTAMP)
-				tv = (struct timeval *) CMSG_DATA(cmsg);
+			if (cmsg->cmsg_type == SCM_TIMESTAMP) {
+				memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv));
+				tv = &ctv;
+			}
 		}
 
 		opcode = btohs(hdr.opcode);
diff --git a/monitor/hcidump.c b/monitor/hcidump.c
index 373d2f5..c850d82 100644
--- a/monitor/hcidump.c
+++ b/monitor/hcidump.c
@@ -130,7 +130,8 @@ static void device_callback(int fd, uint32_t events, void *user_data)
 	while (1) {
 		struct cmsghdr *cmsg;
 		struct timeval *tv = NULL;
-		int *dir = NULL;
+		struct timeval ctv;
+		int dir = -1;
 		ssize_t len;
 
 		len = recvmsg(fd, &msg, MSG_DONTWAIT);
@@ -144,15 +145,18 @@ static void device_callback(int fd, uint32_t events, void *user_data)
 
 			switch (cmsg->cmsg_type) {
 			case HCI_DATA_DIR:
-				dir = (int *) CMSG_DATA(cmsg);
+				dir = bt_get_unaligned(CMSG_DATA(cmsg), int);
+
 				break;
 			case HCI_CMSG_TSTAMP:
-				tv = (struct timeval *) CMSG_DATA(cmsg);
+				memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv));
+				tv = &ctv;
+
 				break;
 			}
 		}
 
-		if (!dir || len < 1)
+		if (dir < 0 || len < 1)
 			continue;
 
 		switch (buf[0]) {
@@ -163,11 +167,11 @@ static void device_callback(int fd, uint32_t events, void *user_data)
 			packet_hci_event(tv, data->index, buf + 1, len - 1);
 			break;
 		case HCI_ACLDATA_PKT:
-			packet_hci_acldata(tv, data->index, !!(*dir),
+			packet_hci_acldata(tv, data->index, !!dir,
 							buf + 1, len - 1);
 			break;
 		case HCI_SCODATA_PKT:
-			packet_hci_scodata(tv, data->index, !!(*dir),
+			packet_hci_scodata(tv, data->index, !!dir,
 							buf + 1, len - 1);
 			break;
 		}
@@ -314,6 +318,7 @@ static void stack_internal_callback(int fd, uint32_t events, void *user_data)
 	evt_stack_internal *si;
 	evt_si_device *sd;
 	struct timeval *tv = NULL;
+	struct timeval ctv;
 	uint8_t type = 0xff, bus = 0xff;
 	char str[18], name[8] = "";
 	bdaddr_t bdaddr;
@@ -345,7 +350,9 @@ static void stack_internal_callback(int fd, uint32_t events, void *user_data)
 
 		switch (cmsg->cmsg_type) {
 		case HCI_CMSG_TSTAMP:
-			tv = (struct timeval *) CMSG_DATA(cmsg);
+			memcpy(&ctv, CMSG_DATA(cmsg), sizeof(ctv));
+			tv = &ctv;
+
 			break;
 		}
 	}
-- 
1.7.9.5


^ permalink raw reply related

* [RFC v4 16/18] sap-u8500: Fix compile error due to unaligned memory access
From: Szymon Janc @ 2012-09-04 14:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1346769697-9930-1-git-send-email-szymon.janc@tieto.com>

This fix following compilation error on ARM.

  CC     profiles/sap/sap-u8500.o
profiles/sap/sap-u8500.c: In function recv_card_status:
profiles/sap/sap-u8500.c:323:16: error: cast increases required
	alignment of target type [-Werror=cast-align]
profiles/sap/sap-u8500.c: In function recv_response:
profiles/sap/sap-u8500.c:423:12: error: cast increases required
	alignment of target type [-Werror=cast-align]
cc1: all warnings being treated as errors

---
 profiles/sap/sap-u8500.c |   10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/profiles/sap/sap-u8500.c b/profiles/sap/sap-u8500.c
index f07209d..8938c84 100644
--- a/profiles/sap/sap-u8500.c
+++ b/profiles/sap/sap-u8500.c
@@ -32,6 +32,8 @@
 #include <sys/socket.h>
 #include <sys/un.h>
 
+#include <bluetooth/bluetooth.h>
+
 #include "log.h"
 #include "sap.h"
 
@@ -313,16 +315,16 @@ static void recv_status(uint32_t status)
 
 static void recv_card_status(uint32_t status, uint8_t *param)
 {
-	uint32_t *card_status;
+	uint32_t card_status;
 	uint8_t result;
 	uint8_t iccrs;
 
 	if (status != STE_STATUS_OK)
 		return;
 
-	card_status = (uint32_t *)param;
+	card_status = bt_get_unaligned(param, uint32_t);
 
-	if (get_sap_reader_status(*card_status, &iccrs) < 0)
+	if (get_sap_reader_status(card_status, &iccrs) < 0)
 		result = SAP_RESULT_ERROR_NO_REASON;
 	else
 		result = get_sap_result(STE_GET_STATUS_MSG, status);
@@ -420,7 +422,7 @@ static void recv_response(struct ste_message *msg)
 	}
 
 	param = msg->payload;
-	status = *(uint32_t *)param;
+	status = bt_get_unaligned(param, uint32_t);
 	param += sizeof(status);
 
 	SAP_VDBG("status 0x%x", status);
-- 
1.7.9.5


^ permalink raw reply related

* [RFC v4 15/18] Refactor bt_get_unaligned macro
From: Szymon Janc @ 2012-09-04 14:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1346769697-9930-1-git-send-email-szymon.janc@tieto.com>

Use extra parameter type for bt_get_unaligned to avoid pointer casting
which might trigger compile time errors due to unaligned memory access.

---
 attrib/att.h       |    6 +++---
 lib/bluetooth.h    |   28 ++++++++++++++--------------
 lib/sdp.c          |   22 +++++++++++-----------
 src/sdpd-request.c |    4 ++--
 4 files changed, 30 insertions(+), 30 deletions(-)

diff --git a/attrib/att.h b/attrib/att.h
index a563255..6101dac 100644
--- a/attrib/att.h
+++ b/attrib/att.h
@@ -115,19 +115,19 @@ struct att_range {
 static inline uint8_t att_get_u8(const void *ptr)
 {
 	const uint8_t *u8_ptr = ptr;
-	return bt_get_unaligned(u8_ptr);
+	return bt_get_unaligned(u8_ptr, uint8_t);
 }
 
 static inline uint16_t att_get_u16(const void *ptr)
 {
 	const uint16_t *u16_ptr = ptr;
-	return btohs(bt_get_unaligned(u16_ptr));
+	return btohs(bt_get_unaligned(u16_ptr, uint16_t));
 }
 
 static inline uint32_t att_get_u32(const void *ptr)
 {
 	const uint32_t *u32_ptr = ptr;
-	return btohl(bt_get_unaligned(u32_ptr));
+	return btohl(bt_get_unaligned(u32_ptr, uint32_t));
 }
 
 static inline uint128_t att_get_u128(const void *ptr)
diff --git a/lib/bluetooth.h b/lib/bluetooth.h
index 161b7bd..898a122 100644
--- a/lib/bluetooth.h
+++ b/lib/bluetooth.h
@@ -137,10 +137,10 @@ enum {
 #endif
 
 /* Bluetooth unaligned access */
-#define bt_get_unaligned(ptr)			\
+#define bt_get_unaligned(ptr, type)		\
 ({						\
 	struct __attribute__((packed)) {	\
-		typeof(*(ptr)) __v;		\
+		type __v;			\
 	} *__p = (typeof(__p)) (ptr);		\
 	__p->__v;				\
 })
@@ -156,32 +156,32 @@ do {						\
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 static inline uint64_t bt_get_le64(const void *ptr)
 {
-	return bt_get_unaligned((const uint64_t *) ptr);
+	return bt_get_unaligned(ptr, uint64_t);
 }
 
 static inline uint64_t bt_get_be64(const void *ptr)
 {
-	return bswap_64(bt_get_unaligned((const uint64_t *) ptr));
+	return bswap_64(bt_get_unaligned(ptr, uint64_t));
 }
 
 static inline uint32_t bt_get_le32(const void *ptr)
 {
-	return bt_get_unaligned((const uint32_t *) ptr);
+	return bt_get_unaligned(ptr, uint32_t);
 }
 
 static inline uint32_t bt_get_be32(const void *ptr)
 {
-	return bswap_32(bt_get_unaligned((const uint32_t *) ptr));
+	return bswap_32(bt_get_unaligned(ptr, uint32_t));
 }
 
 static inline uint16_t bt_get_le16(const void *ptr)
 {
-	return bt_get_unaligned((const uint16_t *) ptr);
+	return bt_get_unaligned(ptr, uint16_t);
 }
 
 static inline uint16_t bt_get_be16(const void *ptr)
 {
-	return bswap_16(bt_get_unaligned((const uint16_t *) ptr));
+	return bswap_16(bt_get_unaligned(ptr, uint16_t));
 }
 
 static inline void bt_put_le64(uint64_t val, const void *ptr)
@@ -217,32 +217,32 @@ static inline void bt_put_be16(uint16_t val, const void *ptr)
 #elif __BYTE_ORDER == __BIG_ENDIAN
 static inline uint64_t bt_get_le64(const void *ptr)
 {
-	return bswap_64(bt_get_unaligned((const uint64_t *) ptr));
+	return bswap_64(bt_get_unaligned(ptr, uint64_t));
 }
 
 static inline uint64_t bt_get_be64(const void *ptr)
 {
-	return bt_get_unaligned((const uint64_t *) ptr);
+	return bt_get_unaligned(ptr, uint64_t);
 }
 
 static inline uint32_t bt_get_le32(const void *ptr)
 {
-	return bswap_32(bt_get_unaligned((const uint32_t *) ptr));
+	return bswap_32(bt_get_unaligned(ptr, uint32_t));
 }
 
 static inline uint32_t bt_get_be32(const void *ptr)
 {
-	return bt_get_unaligned((const uint32_t *) ptr);
+	return bt_get_unaligned(ptr, uint32_t);
 }
 
 static inline uint16_t bt_get_le16(const void *ptr)
 {
-	return bswap_16(bt_get_unaligned((const uint16_t *) ptr));
+	return bswap_16(bt_get_unaligned(ptr, uint16_t));
 }
 
 static inline uint16_t bt_get_be16(const void *ptr)
 {
-	return bt_get_unaligned((const uint16_t *) ptr);
+	return bt_get_unaligned(ptr, uint16_t);
 }
 
 static inline void bt_put_le64(uint64_t val, const void *ptr)
diff --git a/lib/sdp.c b/lib/sdp.c
index 1a5bf01..a533b12 100644
--- a/lib/sdp.c
+++ b/lib/sdp.c
@@ -376,27 +376,27 @@ sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value,
 		d->unitSize += sizeof(int8_t);
 		break;
 	case SDP_UINT16:
-		d->val.uint16 = bt_get_unaligned((uint16_t *) value);
+		d->val.uint16 = bt_get_unaligned(value, uint16_t);
 		d->unitSize += sizeof(uint16_t);
 		break;
 	case SDP_INT16:
-		d->val.int16 = bt_get_unaligned((int16_t *) value);
+		d->val.int16 = bt_get_unaligned(value, int16_t);
 		d->unitSize += sizeof(int16_t);
 		break;
 	case SDP_UINT32:
-		d->val.uint32 = bt_get_unaligned((uint32_t *) value);
+		d->val.uint32 = bt_get_unaligned(value, uint32_t);
 		d->unitSize += sizeof(uint32_t);
 		break;
 	case SDP_INT32:
-		d->val.int32 = bt_get_unaligned((int32_t *) value);
+		d->val.int32 = bt_get_unaligned(value, int32_t);
 		d->unitSize += sizeof(int32_t);
 		break;
 	case SDP_INT64:
-		d->val.int64 = bt_get_unaligned((int64_t *) value);
+		d->val.int64 = bt_get_unaligned(value, int64_t);
 		d->unitSize += sizeof(int64_t);
 		break;
 	case SDP_UINT64:
-		d->val.uint64 = bt_get_unaligned((uint64_t *) value);
+		d->val.uint64 = bt_get_unaligned(value, uint64_t);
 		d->unitSize += sizeof(uint64_t);
 		break;
 	case SDP_UINT128:
@@ -408,11 +408,11 @@ sdp_data_t *sdp_data_alloc_with_length(uint8_t dtd, const void *value,
 		d->unitSize += sizeof(uint128_t);
 		break;
 	case SDP_UUID16:
-		sdp_uuid16_create(&d->val.uuid, bt_get_unaligned((uint16_t *) value));
+		sdp_uuid16_create(&d->val.uuid, bt_get_unaligned(value, uint16_t));
 		d->unitSize += sizeof(uint16_t);
 		break;
 	case SDP_UUID32:
-		sdp_uuid32_create(&d->val.uuid, bt_get_unaligned((uint32_t *) value));
+		sdp_uuid32_create(&d->val.uuid, bt_get_unaligned(value, uint32_t));
 		d->unitSize += sizeof(uint32_t);
 		break;
 	case SDP_UUID128:
@@ -2991,7 +2991,7 @@ int sdp_device_record_unregister_binary(sdp_session_t *session, bdaddr_t *device
 
 	rsphdr = (sdp_pdu_hdr_t *) rspbuf;
 	p = rspbuf + sizeof(sdp_pdu_hdr_t);
-	status = bt_get_unaligned((uint16_t *) p);
+	status = bt_get_unaligned(p, uint16_t);
 
 	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
 		/* For this case the status always is invalid record handle */
@@ -3096,7 +3096,7 @@ int sdp_device_record_update(sdp_session_t *session, bdaddr_t *device, const sdp
 
 	rsphdr = (sdp_pdu_hdr_t *) rspbuf;
 	p = rspbuf + sizeof(sdp_pdu_hdr_t);
-	status = bt_get_unaligned((uint16_t *) p);
+	status = bt_get_unaligned(p, uint16_t);
 
 	if (rsphdr->pdu_id == SDP_ERROR_RSP) {
 		/* The status can be invalid sintax or invalid record handle */
@@ -4153,7 +4153,7 @@ int sdp_process(sdp_session_t *session)
 			pdata += sizeof(uint16_t); /* point to csrc */
 
 			/* the first csrc contains the sum of partial csrc responses */
-			*pcsrc += bt_get_unaligned((uint16_t *) pdata);
+			*pcsrc += bt_get_unaligned(pdata, uint16_t);
 
 			pdata += sizeof(uint16_t); /* point to the first handle */
 			rsp_count = csrc * 4;
diff --git a/src/sdpd-request.c b/src/sdpd-request.c
index 2af743e..6bf7f89 100644
--- a/src/sdpd-request.c
+++ b/src/sdpd-request.c
@@ -183,7 +183,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p
 				pElem = (char *) aid;
 			} else {
 				pElem = malloc(sizeof(uint16_t));
-				bt_put_be16(bt_get_unaligned((uint16_t *)p), pElem);
+				bt_put_be16(bt_get_unaligned(p, uint16_t), pElem);
 			}
 			p += sizeof(uint16_t);
 			seqlen += sizeof(uint16_t);
@@ -207,7 +207,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p
 				pElem = (char *) aid;
 			} else {
 				pElem = malloc(sizeof(uint32_t));
-				bt_put_be32(bt_get_unaligned((uint32_t *)p), pElem);
+				bt_put_be32(bt_get_unaligned(p, uint32_t), pElem);
 			}
 			p += sizeof(uint32_t);
 			seqlen += sizeof(uint32_t);
-- 
1.7.9.5


^ permalink raw reply related

* [RFC v4 14/18] mgmt: Use bt_get_* helper functions to access unaligned memory
From: Szymon Janc @ 2012-09-04 14:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1346769697-9930-1-git-send-email-szymon.janc@tieto.com>

---
 src/mgmt.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/src/mgmt.c b/src/mgmt.c
index 45a5c90..c64eb68 100644
--- a/src/mgmt.c
+++ b/src/mgmt.c
@@ -100,7 +100,7 @@ static void read_version_complete(int sk, void *buf, size_t len)
 		abort();
 	}
 
-	mgmt_revision = btohs(bt_get_unaligned(&rp->revision));
+	mgmt_revision = bt_get_le16(&rp->revision);
 	mgmt_version = rp->version;
 
 	DBG("version %u revision %u", mgmt_version, mgmt_revision);
@@ -923,7 +923,7 @@ static void read_index_list_complete(int sk, void *buf, size_t len)
 		return;
 	}
 
-	num = btohs(bt_get_unaligned(&rp->num_controllers));
+	num = bt_get_le16(&rp->num_controllers);
 
 	if (num * sizeof(uint16_t) + sizeof(*rp) != len) {
 		error("Incorrect packet size for index list event");
@@ -933,7 +933,7 @@ static void read_index_list_complete(int sk, void *buf, size_t len)
 	for (i = 0; i < num; i++) {
 		uint16_t index;
 
-		index = btohs(bt_get_unaligned(&rp->index[i]));
+		index = bt_get_le16(&rp->index);
 
 		add_controller(index);
 		read_info(sk, index);
@@ -1033,7 +1033,7 @@ static void read_info_complete(int sk, uint16_t index, void *buf, size_t len)
 
 	bacpy(&info->bdaddr, &rp->bdaddr);
 	info->version = rp->version;
-	info->manufacturer = btohs(bt_get_unaligned(&rp->manufacturer));
+	info->manufacturer = bt_get_le16(&rp->manufacturer);
 
 	memcpy(&info->supported_settings, &rp->supported_settings,
 					sizeof(info->supported_settings));
@@ -1365,7 +1365,7 @@ static void mgmt_cmd_complete(int sk, uint16_t index, void *buf, size_t len)
 		return;
 	}
 
-	opcode = btohs(bt_get_unaligned(&ev->opcode));
+	opcode = bt_get_le16(&ev->opcode);
 
 	len -= sizeof(*ev);
 
@@ -1498,7 +1498,7 @@ static void mgmt_cmd_status(int sk, uint16_t index, void *buf, size_t len)
 		return;
 	}
 
-	opcode = btohs(bt_get_unaligned(&ev->opcode));
+	opcode = bt_get_le16(&ev->opcode);
 
 	if (!ev->status) {
 		DBG("%s (0x%04x) cmd_status %u", mgmt_opstr(opcode), opcode,
@@ -1824,9 +1824,9 @@ static gboolean mgmt_event(GIOChannel *io, GIOCondition cond, gpointer user_data
 		return TRUE;
 	}
 
-	opcode = btohs(bt_get_unaligned(&hdr->opcode));
-	len = btohs(bt_get_unaligned(&hdr->len));
-	index = btohs(bt_get_unaligned(&hdr->index));
+	opcode = bt_get_le16(&hdr->opcode);
+	len = bt_get_le16(&hdr->len);
+	index = bt_get_le16(&hdr->index);
 
 	if (ret != MGMT_HDR_SIZE + len) {
 		error("Packet length mismatch. ret %zd len %u", ret, len);
-- 
1.7.9.5


^ permalink raw reply related

* [RFC v4 13/18] eir: Use bt_get_* helper functions to access unaligned memory
From: Szymon Janc @ 2012-09-04 14:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1346769697-9930-1-git-send-email-szymon.janc@tieto.com>

---
 src/eir.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/eir.c b/src/eir.c
index 9d42917..50912a0 100644
--- a/src/eir.c
+++ b/src/eir.c
@@ -55,7 +55,8 @@ static void eir_parse_uuid16(struct eir_data *eir, void *data, uint8_t len)
 
 	service.type = SDP_UUID16;
 	for (i = 0; i < len / 2; i++, uuid16++) {
-		service.value.uuid16 = btohs(bt_get_unaligned(uuid16));
+		service.value.uuid16 = bt_get_le16(uuid16);
+
 		uuid_str = bt_uuid2string(&service);
 		eir->services = g_slist_append(eir->services, uuid_str);
 	}
@@ -70,7 +71,8 @@ static void eir_parse_uuid32(struct eir_data *eir, void *data, uint8_t len)
 
 	service.type = SDP_UUID32;
 	for (i = 0; i < len / 4; i++, uuid32++) {
-		service.value.uuid32 = btohl(bt_get_unaligned(uuid32));
+		service.value.uuid32 = bt_get_le32(uuid32);
+
 		uuid_str = bt_uuid2string(&service);
 		eir->services = g_slist_append(eir->services, uuid_str);
 	}
-- 
1.7.9.5


^ permalink raw reply related

* [RFC v4 12/18] avrcp: Fix compilation errors due to unaligned memory access
From: Szymon Janc @ 2012-09-04 14:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1346769697-9930-1-git-send-email-szymon.janc@tieto.com>

This fix following build errors on ARM.

  CC     audio/bluetoothd-avrcp.o
audio/avrcp.c: In function avrcp_handle_get_element_attributes:
audio/avrcp.c:667:25: error: cast increases required alignment of
	target type [-Werror=cast-align]
audio/avrcp.c:690:20: error: cast increases required alignment of
	target type [-Werror=cast-align]
cc1: all warnings being treated as errors
make[1]: *** [audio/bluetoothd-avrcp.o] Error 1
make: *** [all] Error 2

---
 audio/avrcp.c |   10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/audio/avrcp.c b/audio/avrcp.c
index 0688ffa..27be7e8 100644
--- a/audio/avrcp.c
+++ b/audio/avrcp.c
@@ -665,13 +665,13 @@ static uint8_t avrcp_handle_get_element_attributes(struct avrcp_player *player,
 						uint8_t transaction)
 {
 	uint16_t len = ntohs(pdu->params_len);
-	uint64_t *identifier = (uint64_t *) &pdu->params[0];
+	uint64_t identifier = bt_get_le64(&pdu->params[0]);
 	uint16_t pos;
 	uint8_t nattr;
 	GList *attr_ids;
 	uint16_t offset;
 
-	if (len < 9 || *identifier != 0)
+	if (len < 9 || identifier != 0)
 		goto err;
 
 	nattr = pdu->params[8];
@@ -688,10 +688,10 @@ static uint8_t avrcp_handle_get_element_attributes(struct avrcp_player *player,
 		len = g_list_length(attr_ids);
 	} else {
 		unsigned int i;
-		uint32_t *attr = (uint32_t *) &pdu->params[9];
+		for (i = 0, len = 0, attr_ids = NULL; i < nattr; i++) {
+			uint32_t id;
 
-		for (i = 0, len = 0, attr_ids = NULL; i < nattr; i++, attr++) {
-			uint32_t id = ntohl(bt_get_unaligned(attr));
+			id = bt_get_be32(&pdu->params[9] + (i * sizeof(id)));
 
 			/* Don't add invalid attributes */
 			if (id == AVRCP_MEDIA_ATTRIBUTE_ILLEGAL ||
-- 
1.7.9.5


^ permalink raw reply related

* [RFC v4 11/18] hciemu: Fix build errors due to unaligned memory access
From: Szymon Janc @ 2012-09-04 14:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1346769697-9930-1-git-send-email-szymon.janc@tieto.com>

This fix following build errors on ARM.

  CC     test/hciemu.o
test/hciemu.c: In function num_completed_pkts:
test/hciemu.c:429:4: error: cast increases required alignment of target
	 type [-Werror=cast-align]
test/hciemu.c:430:4: error: cast increases required alignment of target
	type [-Werror=cast-align]
cc1: all warnings being treated as errors
make[1]: *** [test/hciemu.o] Error 1
make: *** [all] Error 2

---
 test/hciemu.c |    6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/test/hciemu.c b/test/hciemu.c
index 4c62223..a125cf4 100644
--- a/test/hciemu.c
+++ b/test/hciemu.c
@@ -426,8 +426,10 @@ static void num_completed_pkts(struct vhci_conn *conn)
 	np = (void *) ptr; ptr += EVT_NUM_COMP_PKTS_SIZE;
 	np->num_hndl = 1;
 
-	*((uint16_t *) ptr) = htobs(conn->handle); ptr += 2;
-	*((uint16_t *) ptr) = htobs(vdev.acl_cnt); ptr += 2;
+	bt_put_le16(conn->handle, ptr);
+	ptr += 2;
+	bt_put_le16(vdev.acl_cnt, ptr);
+	ptr += 2;
 
 	write_snoop(vdev.dd, HCI_EVENT_PKT, 1, buf, ptr - buf);
 
-- 
1.7.9.5


^ permalink raw reply related

* [RFC v4 10/18] sdpd-service: Fix build errors due to unaligned memory access
From: Szymon Janc @ 2012-09-04 14:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1346769697-9930-1-git-send-email-szymon.janc@tieto.com>

This fix number of build errors on ARM similar to one below.

  CC     src/bluetooth-sdpd-service.o
src/sdpd-service.c: In function service_remove_req:
src/sdpd-service.c:517:20: error: cast increases required alignment of
	target type [-Werror=cast-align]
src/sdpd-service.c:517:20: error: cast increases required alignment of
	target type [-Werror=cast-align]
src/sdpd-service.c:536:2: error: cast increases required alignment of
	target type [-Werror=cast-align]
src/sdpd-service.c:536:2: error: cast increases required alignment of
	target type [-Werror=cast-align]
cc1: all warnings being treated as errors

---
 src/sdpd-service.c |   21 ++++++++++-----------
 1 file changed, 10 insertions(+), 11 deletions(-)

diff --git a/src/sdpd-service.c b/src/sdpd-service.c
index 39e05ab..b43ddc2 100644
--- a/src/sdpd-service.c
+++ b/src/sdpd-service.c
@@ -317,7 +317,7 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p,
 		return NULL;
 	}
 
-	lookAheadAttrId = ntohs(bt_get_unaligned((uint16_t *) (p + sizeof(uint8_t))));
+	lookAheadAttrId = bt_get_be16(p + sizeof(uint8_t));
 
 	SDPDBG("Look ahead attr id : %d", lookAheadAttrId);
 
@@ -327,9 +327,8 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p,
 			SDPDBG("Unexpected end of packet");
 			return NULL;
 		}
-		handle = ntohl(bt_get_unaligned((uint32_t *) (p +
-				sizeof(uint8_t) + sizeof(uint16_t) +
-				sizeof(uint8_t))));
+		handle = bt_get_be32(p + sizeof(uint8_t) + sizeof(uint16_t) +
+							sizeof(uint8_t));
 		SDPDBG("SvcRecHandle : 0x%x", handle);
 		rec = sdp_record_find(handle);
 	} else if (handleExpected != 0xffffffff)
@@ -363,7 +362,7 @@ static sdp_record_t *extract_pdu_server(bdaddr_t *device, uint8_t *p,
 							seqlen, localExtractedLength);
 		dtd = *(uint8_t *) p;
 
-		attrId = ntohs(bt_get_unaligned((uint16_t *) (p + attrSize)));
+		attrId = bt_get_be16(p + attrSize);
 		attrSize += sizeof(uint16_t);
 
 		SDPDBG("DTD of attrId : %d Attr id : 0x%x", dtd, attrId);
@@ -454,13 +453,13 @@ success:
 	update_db_timestamp();
 
 	/* Build a rsp buffer */
-	bt_put_unaligned(htonl(rec->handle), (uint32_t *) rsp->data);
+	bt_put_be32(rec->handle, rsp->data);
 	rsp->data_size = sizeof(uint32_t);
 
 	return 0;
 
 invalid:
-	bt_put_unaligned(htons(SDP_INVALID_SYNTAX), (uint16_t *) rsp->data);
+	bt_put_be16(SDP_INVALID_SYNTAX, rsp->data);
 	rsp->data_size = sizeof(uint16_t);
 
 	return -1;
@@ -475,7 +474,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp)
 	int status = 0, scanned = 0;
 	uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t);
 	int bufsize = req->len - sizeof(sdp_pdu_hdr_t);
-	uint32_t handle = ntohl(bt_get_unaligned((uint32_t *) p));
+	uint32_t handle = bt_get_be32(p);
 
 	SDPDBG("Svc Rec Handle: 0x%x", handle);
 
@@ -503,7 +502,7 @@ int service_update_req(sdp_req_t *req, sdp_buf_t *rsp)
 
 done:
 	p = rsp->data;
-	bt_put_unaligned(htons(status), (uint16_t *) p);
+	bt_put_be16(status, p);
 	rsp->data_size = sizeof(uint16_t);
 	return status;
 }
@@ -514,7 +513,7 @@ done:
 int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp)
 {
 	uint8_t *p = req->buf + sizeof(sdp_pdu_hdr_t);
-	uint32_t handle = ntohl(bt_get_unaligned((uint32_t *) p));
+	uint32_t handle = bt_get_be32(p);
 	sdp_record_t *rec;
 	int status = 0;
 
@@ -533,7 +532,7 @@ int service_remove_req(sdp_req_t *req, sdp_buf_t *rsp)
 	}
 
 	p = rsp->data;
-	bt_put_unaligned(htons(status), (uint16_t *) p);
+	bt_put_be16(status, p);
 	rsp->data_size = sizeof(uint16_t);
 
 	return status;
-- 
1.7.9.5


^ permalink raw reply related

* [RFC v4 09/18] sdpd-request: Fix build errors due to unaligned memory access
From: Szymon Janc @ 2012-09-04 14:41 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Szymon Janc
In-Reply-To: <1346769697-9930-1-git-send-email-szymon.janc@tieto.com>

This fix number of build errors on ARM similar to one below.

  CC     src/bluetooth-sdpd-request.o
src/sdpd-request.c: In function extra_des:
src/sdpd-request.c:181:5: error: cast increases required alignment
    of targettype [-Werror=cast-align]

---
 src/sdpd-request.c |   62 ++++++++++++++++++++++++++++------------------------
 1 file changed, 33 insertions(+), 29 deletions(-)

diff --git a/src/sdpd-request.c b/src/sdpd-request.c
index 6a903c6..2af743e 100644
--- a/src/sdpd-request.c
+++ b/src/sdpd-request.c
@@ -139,6 +139,7 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p
 	for (;;) {
 		char *pElem = NULL;
 		int localSeqLength = 0;
+		uuid_t *puuid;
 
 		if (bufsize < sizeof(uint8_t)) {
 			SDPDBG("->Unexpected end of buffer");
@@ -178,11 +179,11 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p
 				struct attrid *aid;
 				aid = malloc(sizeof(struct attrid));
 				aid->dtd = dataType;
-				bt_put_unaligned(ntohs(bt_get_unaligned((uint16_t *)p)), (uint16_t *)&aid->uint16);
+				aid->uint16 = bt_get_be16(p);
 				pElem = (char *) aid;
 			} else {
 				pElem = malloc(sizeof(uint16_t));
-				bt_put_unaligned(ntohs(bt_get_unaligned((uint16_t *)p)), (uint16_t *)pElem);
+				bt_put_be16(bt_get_unaligned((uint16_t *)p), pElem);
 			}
 			p += sizeof(uint16_t);
 			seqlen += sizeof(uint16_t);
@@ -201,11 +202,12 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p
 				struct attrid *aid;
 				aid = malloc(sizeof(struct attrid));
 				aid->dtd = dataType;
-				bt_put_unaligned(ntohl(bt_get_unaligned((uint32_t *)p)), (uint32_t *)&aid->uint32);
+				aid->uint32 = bt_get_be32(p);
+
 				pElem = (char *) aid;
 			} else {
 				pElem = malloc(sizeof(uint32_t));
-				bt_put_unaligned(ntohl(bt_get_unaligned((uint32_t *)p)), (uint32_t *)pElem);
+				bt_put_be32(bt_get_unaligned((uint32_t *)p), pElem);
 			}
 			p += sizeof(uint32_t);
 			seqlen += sizeof(uint32_t);
@@ -214,12 +216,14 @@ static int extract_des(uint8_t *buf, int len, sdp_list_t **svcReqSeq, uint8_t *p
 		case SDP_UUID16:
 		case SDP_UUID32:
 		case SDP_UUID128:
-			pElem = malloc(sizeof(uuid_t));
-			status = sdp_uuid_extract(p, bufsize, (uuid_t *) pElem, &localSeqLength);
+			puuid = malloc(sizeof(uuid_t));
+			status = sdp_uuid_extract(p, bufsize, puuid, &localSeqLength);
 			if (status < 0) {
-				free(pElem);
+				free(puuid);
 				goto failed;
 			}
+
+			pElem = (char *) puuid;
 			seqlen += localSeqLength;
 			p += localSeqLength;
 			bufsize -= localSeqLength;
@@ -359,7 +363,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
 	uint8_t *pCacheBuffer = NULL;
 	int handleSize = 0;
 	uint32_t cStateId = 0;
-	short *pTotalRecordCount, *pCurrentRecordCount;
+	uint8_t *pTotalRecordCount, *pCurrentRecordCount;
 	uint8_t *pdata = req->buf + sizeof(sdp_pdu_hdr_t);
 	size_t data_left = req->len - sizeof(sdp_pdu_hdr_t);
 
@@ -385,7 +389,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
 		goto done;
 	}
 
-	expected = ntohs(bt_get_unaligned((uint16_t *)pdata));
+	expected = bt_get_be16(pdata);
 
 	SDPDBG("Expected count: %d", expected);
 	SDPDBG("Bytes scanned : %d", scanned);
@@ -409,14 +413,14 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
 	pdata = buf->data;
 
 	/* total service record count = 0 */
-	pTotalRecordCount = (short *)pdata;
-	bt_put_unaligned(0, (uint16_t *)pdata);
+	pTotalRecordCount = pdata;
+	bt_put_be16(0, pdata);
 	pdata += sizeof(uint16_t);
 	buf->data_size += sizeof(uint16_t);
 
 	/* current service record count = 0 */
-	pCurrentRecordCount = (short *)pdata;
-	bt_put_unaligned(0, (uint16_t *)pdata);
+	pCurrentRecordCount = pdata;
+	bt_put_be16(0, pdata);
 	pdata += sizeof(uint16_t);
 	buf->data_size += sizeof(uint16_t);
 
@@ -433,7 +437,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
 			if (sdp_match_uuid(pattern, rec->pattern) > 0 &&
 					sdp_check_access(rec->handle, &req->device)) {
 				rsp_count++;
-				bt_put_unaligned(htonl(rec->handle), (uint32_t *)pdata);
+				bt_put_be32(rec->handle, pdata);
 				pdata += sizeof(uint32_t);
 				handleSize += sizeof(uint32_t);
 			}
@@ -442,8 +446,8 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
 		SDPDBG("Match count: %d", rsp_count);
 
 		buf->data_size += handleSize;
-		bt_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount);
-		bt_put_unaligned(htons(rsp_count), (uint16_t *)pCurrentRecordCount);
+		bt_put_be16(rsp_count, pTotalRecordCount);
+		bt_put_be16(rsp_count, pCurrentRecordCount);
 
 		if (rsp_count > actual) {
 			/* cache the rsp and generate a continuation state */
@@ -472,7 +476,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
 			if (pCache) {
 				pCacheBuffer = pCache->data;
 				/* get the rsp_count from the cached buffer */
-				rsp_count = ntohs(bt_get_unaligned((uint16_t *)pCacheBuffer));
+				rsp_count = bt_get_be16(pCacheBuffer);
 
 				/* get index of the last sdp_record_t sent */
 				lastIndex = cstate->cStateValue.lastIndexSent;
@@ -490,7 +494,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
 		 * current record count and increment the cached
 		 * buffer pointer to beyond the counters
 		 */
-		pdata = (uint8_t *) pCurrentRecordCount + sizeof(uint16_t);
+		pdata = pCurrentRecordCount + sizeof(uint16_t);
 
 		/* increment beyond the totalCount and the currentCount */
 		pCacheBuffer += 2 * sizeof(uint16_t);
@@ -498,7 +502,7 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
 		if (cstate) {
 			handleSize = 0;
 			for (i = lastIndex; (i - lastIndex) < actual && i < rsp_count; i++) {
-				bt_put_unaligned(bt_get_unaligned((uint32_t *)(pCacheBuffer + i * sizeof(uint32_t))), (uint32_t *)pdata);
+				memcpy(pdata, pCacheBuffer + i * sizeof(uint32_t), sizeof(uint32_t));
 				pdata += sizeof(uint32_t);
 				handleSize += sizeof(uint32_t);
 			}
@@ -508,8 +512,8 @@ static int service_search_req(sdp_req_t *req, sdp_buf_t *buf)
 		}
 
 		buf->data_size += handleSize;
-		bt_put_unaligned(htons(rsp_count), (uint16_t *)pTotalRecordCount);
-		bt_put_unaligned(htons(i - lastIndex), (uint16_t *)pCurrentRecordCount);
+		bt_put_be16(rsp_count, pTotalRecordCount);
+		bt_put_be16(i - lastIndex, pCurrentRecordCount);
 
 		if (i == rsp_count) {
 			/* set "null" continuationState */
@@ -571,12 +575,12 @@ static int extract_attrs(sdp_record_t *rec, sdp_list_t *seq, sdp_buf_t *buf)
 		SDPDBG("AttrDataType : %d", aid->dtd);
 
 		if (aid->dtd == SDP_UINT16) {
-			uint16_t attr = bt_get_unaligned((uint16_t *)&aid->uint16);
+			uint16_t attr = aid->uint16;
 			sdp_data_t *a = sdp_data_get(rec, attr);
 			if (a)
 				sdp_append_to_pdu(buf, a);
 		} else if (aid->dtd == SDP_UINT32) {
-			uint32_t range = bt_get_unaligned((uint32_t *)&aid->uint32);
+			uint32_t range = aid->uint32;
 			uint16_t attr;
 			uint16_t low = (0xffff0000 & range) >> 16;
 			uint16_t high = 0x0000ffff & range;
@@ -639,7 +643,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf)
 		goto done;
 	}
 
-	handle = ntohl(bt_get_unaligned((uint32_t *)pdata));
+	handle = bt_get_be32(pdata);
 
 	pdata += sizeof(uint32_t);
 	data_left -= sizeof(uint32_t);
@@ -649,7 +653,7 @@ static int service_attr_req(sdp_req_t *req, sdp_buf_t *buf)
 		goto done;
 	}
 
-	max_rsp_size = ntohs(bt_get_unaligned((uint16_t *)pdata));
+	max_rsp_size = bt_get_be16(pdata);
 
 	pdata += sizeof(uint16_t);
 	data_left -= sizeof(uint16_t);
@@ -765,7 +769,7 @@ done:
 		return status;
 
 	/* set attribute list byte count */
-	bt_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data);
+	bt_put_be16(buf->data_size - cstate_size, buf->data);
 	buf->data_size += sizeof(uint16_t);
 	return 0;
 }
@@ -806,7 +810,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf)
 		goto done;
 	}
 
-	max = ntohs(bt_get_unaligned((uint16_t *)pdata));
+	max = bt_get_be16(pdata);
 
 	pdata += sizeof(uint16_t);
 	data_left -= sizeof(uint16_t);
@@ -936,7 +940,7 @@ static int service_search_attr_req(sdp_req_t *req, sdp_buf_t *buf)
 
 	if (!status) {
 		/* set attribute list byte count */
-		bt_put_unaligned(htons(buf->data_size - cstate_size), (uint16_t *)buf->data);
+		bt_put_be16(buf->data_size - cstate_size, buf->data);
 		buf->data_size += sizeof(uint16_t);
 	}
 
@@ -1020,7 +1024,7 @@ static void process_request(sdp_req_t *req)
 send_rsp:
 	if (status) {
 		rsphdr->pdu_id = SDP_ERROR_RSP;
-		bt_put_unaligned(htons(status), (uint16_t *)rsp.data);
+		bt_put_be16(status, rsp.data);
 		rsp.data_size = sizeof(uint16_t);
 	}
 
-- 
1.7.9.5


^ permalink raw reply related


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox