Linux bluetooth development
 help / color / mirror / Atom feed
* RE: [BLE] org.bluez.Device1.Connect() returns org.bluez.Error.NotAvailable
From: Ting Chou @ 2012-12-12  9:10 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <20121212075201.GA14256@x220>

Hello Johan,

> -----Original Message-----
> From: Johan Hedberg [mailto:johan.hedberg@gmail.com]
> Sent: Wednesday, December 12, 2012 3:52 PM
> To: Ting Chou
> Cc: linux-bluetooth@vger.kernel.org
> Subject: Re: [BLE] org.bluez.Device1.Connect() returns
> org.bluez.Error.NotAvailable
> 
> Hi Ting,
> 
> On Wed, Dec 12, 2012, Ting Chou wrote:
> > I Found
> > -------
> >
> > - I checked /var/log/syslog and src/device.c, and found
> connect_profiles() is
> >   called twice at the first time calling org.bluez.Device.Connect():
> >
> >   - 1st time
> >     dev->svc_resolved==FALSE, device_resolve_svc() is invoked.
> >
> >   - 2nd time
> >     dev->svc_resolved==TRUE
> >     In the for loop of iterating device profiles, there're two
> profiles:
> >
> >       a) p->auto_connect==FALSE, p->name==deviceinfo, p-
> >local_uuid==NULL
> >       b) p->auto_connect==FALSE, p->name==Health Thermometer GATT
> > driver, p->local_uuid==NULL
> >
> >     Since none of them have auto_connect TRUE, dev->pending==NULL,
> and
> >     btd_error_not_available() is called.
> >
> > - I tried org.bluez.Device1.ConnectProfile() as well, but since all
> the profiles
> >   have local_uuid NULL, find_connectable_profile() return NULL and
> >   btd_error_invalid_args() is called.
> 
> It's not actually local_uuid that is so important but that p->connect
> is set. Also, it'd make much more sense to pass the remote UUID to
> ConnectProfile than the local one and we'll still do this change before
> releasing 5.0. The main thing that needs to be done before that is to
> convert profile->remote_uuids list to a single profile->remote_uuid
> which is a bit of work since some profiles still declare multiple UUIDs.
> 
> So far no LE profile is hooked up to Device.Connect and I'm not sure
> exactly how that should be done since LE device are connected through
> the general connection establishment procedure which requires scanning
> first. Since we already have Device.Pair doing the same as
> CreatePairedDevice in BlueZ 4 (and this should work btw, did you try
> it?) maybe Device.Connect should be roughly the same for LE devices as
> Adapter.CreateDevice is in BlueZ 4? For BR/EDR devices it already
> serves this purpose. The main question is what should be done if
> Device.Connect is called subsequent times as bluetoothd should anyway
> already be doing passive scanning and trying to connect to devices that
> have supported profiles.
> 
> Johan

I tried Device.Pair, it does connect to the LE device like the first call to
Device.Connect, but:

- I can't unpair the device (CancelPairing can't do this).

- If I Device.Disconnect after Device.Pair, then I can't connect to the device
  again by either Device.Connect or Device.Pair:
  - Device1.Connect
    Error org.bluez.Error.NotAvailable: Operation currently not available
  - Device1.Pair
    Error org.bluez.Error.AlreadyExists: Already Exists

I still can't connect to the LE device once I disconnect it.

Thanks,
Ting

^ permalink raw reply

* Re: [PATCH] storage: Remove not used functions
From: Johan Hedberg @ 2012-12-12  8:57 UTC (permalink / raw)
  To: Frédéric Danis; +Cc: linux-bluetooth
In-Reply-To: <1355301688-30095-1-git-send-email-frederic.danis@linux.intel.com>

Hi Frédéric,

On Wed, Dec 12, 2012, Frédéric Danis wrote:
> Those functions are no more used with new storage architecture.
> ---
>  src/storage.c |  590 ---------------------------------------------------------
>  src/storage.h |   43 -----
>  2 files changed, 633 deletions(-)

Applied. Thanks.

Johan

^ permalink raw reply

* [PATCH] storage: Remove not used functions
From: Frédéric Danis @ 2012-12-12  8:41 UTC (permalink / raw)
  To: linux-bluetooth

Those functions are no more used with new storage architecture.
---
 src/storage.c |  590 ---------------------------------------------------------
 src/storage.h |   43 -----
 2 files changed, 633 deletions(-)

diff --git a/src/storage.c b/src/storage.c
index ac66021..5798ccd 100644
--- a/src/storage.c
+++ b/src/storage.c
@@ -65,64 +65,6 @@ static inline int create_filename(char *buf, size_t size,
 	return create_name(buf, size, STORAGEDIR, addr, name);
 }
 
-int read_device_alias(const char *src, const char *dst, uint8_t dst_type,
-						char *alias, size_t size)
-{
-	char filename[PATH_MAX + 1], *tmp;
-	char key[20];
-	int err;
-
-	create_name(filename, PATH_MAX, STORAGEDIR, src, "aliases");
-
-	snprintf(key, sizeof(key), "%17s#%hhu", dst, dst_type);
-
-	tmp = textfile_get(filename, key);
-	if (tmp != NULL)
-		goto done;
-
-	/* Try old format (address only) */
-	key[17] = '\0';
-
-	tmp = textfile_get(filename, key);
-	if (tmp == NULL)
-		return -ENXIO;
-
-done:
-	err = snprintf(alias, size, "%s", tmp);
-
-	free(tmp);
-
-	return err < 0 ? -EIO : 0;
-}
-
-int write_device_alias(const char *src, const char *dst, uint8_t dst_type,
-							const char *alias)
-{
-	char filename[PATH_MAX + 1];
-	char key[20];
-
-	create_name(filename, PATH_MAX, STORAGEDIR, src, "aliases");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	snprintf(key, sizeof(key), "%17s#%hhu", dst, dst_type);
-
-	return textfile_put(filename, key, alias);
-}
-
-int write_discoverable_timeout(const bdaddr_t *bdaddr, int timeout)
-{
-	char filename[PATH_MAX + 1], str[32];
-
-	snprintf(str, sizeof(str), "%d", timeout);
-
-	create_filename(filename, PATH_MAX, bdaddr, "config");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	return textfile_put(filename, "discovto", str);
-}
-
 int read_discoverable_timeout(const char *src, int *timeout)
 {
 	char filename[PATH_MAX + 1], *str;
@@ -143,19 +85,6 @@ int read_discoverable_timeout(const char *src, int *timeout)
 	return 0;
 }
 
-int write_pairable_timeout(const bdaddr_t *bdaddr, int timeout)
-{
-	char filename[PATH_MAX + 1], str[32];
-
-	snprintf(str, sizeof(str), "%d", timeout);
-
-	create_filename(filename, PATH_MAX, bdaddr, "config");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	return textfile_put(filename, "pairto", str);
-}
-
 int read_pairable_timeout(const char *src, int *timeout)
 {
 	char filename[PATH_MAX + 1], *str;
@@ -176,20 +105,6 @@ int read_pairable_timeout(const char *src, int *timeout)
 	return 0;
 }
 
-int write_device_mode(const bdaddr_t *bdaddr, const char *mode)
-{
-	char filename[PATH_MAX + 1];
-
-	create_filename(filename, PATH_MAX, bdaddr, "config");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	if (strcmp(mode, "off") != 0)
-		textfile_put(filename, "onmode", mode);
-
-	return textfile_put(filename, "mode", mode);
-}
-
 int read_device_mode(const char *src, char *mode, int length)
 {
 	char filename[PATH_MAX + 1], *str;
@@ -226,25 +141,6 @@ int read_on_mode(const char *src, char *mode, int length)
 	return 0;
 }
 
-int write_local_name(const bdaddr_t *bdaddr, const char *name)
-{
-	char filename[PATH_MAX + 1], str[249];
-	int i;
-
-	memset(str, 0, sizeof(str));
-	for (i = 0; i < 248 && name[i]; i++)
-		if ((unsigned char) name[i] < 32 || name[i] == 127)
-			str[i] = '.';
-		else
-			str[i] = name[i];
-
-	create_filename(filename, PATH_MAX, bdaddr, "config");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	return textfile_put(filename, "name", str);
-}
-
 int read_local_name(const bdaddr_t *bdaddr, char *name)
 {
 	char filename[PATH_MAX + 1], *str;
@@ -266,19 +162,6 @@ int read_local_name(const bdaddr_t *bdaddr, char *name)
 	return 0;
 }
 
-int write_local_class(const bdaddr_t *bdaddr, uint8_t *class)
-{
-	char filename[PATH_MAX + 1], str[9];
-
-	sprintf(str, "0x%2.2x%2.2x%2.2x", class[2], class[1], class[0]);
-
-	create_filename(filename, PATH_MAX, bdaddr, "config");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	return textfile_put(filename, "class", str);
-}
-
 int read_local_class(const bdaddr_t *bdaddr, uint8_t *class)
 {
 	char filename[PATH_MAX + 1], tmp[3], *str;
@@ -342,117 +225,6 @@ int write_remote_appearance(const bdaddr_t *local, const bdaddr_t *peer,
 	return textfile_put(filename, key, str);
 }
 
-int write_remote_class(const bdaddr_t *local, const bdaddr_t *peer,
-								uint32_t class)
-{
-	char filename[PATH_MAX + 1], addr[18], str[9];
-
-	create_filename(filename, PATH_MAX, local, "classes");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	ba2str(peer, addr);
-	sprintf(str, "0x%6.6x", class);
-
-	return textfile_put(filename, addr, str);
-}
-
-int read_remote_class(const bdaddr_t *local, const bdaddr_t *peer,
-							uint32_t *class)
-{
-	char filename[PATH_MAX + 1], addr[18], *str;
-
-	create_filename(filename, PATH_MAX, local, "classes");
-
-	ba2str(peer, addr);
-
-	str = textfile_get(filename, addr);
-	if (!str)
-		return -ENOENT;
-
-	if (sscanf(str, "%x", class) != 1) {
-		free(str);
-		return -ENOENT;
-	}
-
-	free(str);
-
-	return 0;
-}
-
-int write_device_name(const bdaddr_t *local, const bdaddr_t *peer,
-					uint8_t peer_type, const char *name)
-{
-	char filename[PATH_MAX + 1], key[20], str[HCI_MAX_NAME_LENGTH + 1];
-	int i;
-
-	memset(str, 0, sizeof(str));
-	for (i = 0; i < HCI_MAX_NAME_LENGTH && name[i]; i++)
-		if ((unsigned char) name[i] < 32 || name[i] == 127)
-			str[i] = '.';
-		else
-			str[i] = name[i];
-
-	create_filename(filename, PATH_MAX, local, "names");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	ba2str(peer, key);
-	sprintf(&key[17], "#%hhu", peer_type);
-
-	return textfile_put(filename, key, str);
-}
-
-int read_device_name(const char *src, const char *dst, uint8_t dst_type,
-								char *name)
-{
-	char filename[PATH_MAX + 1], *str, key[20];
-	int len;
-
-	create_name(filename, PATH_MAX, STORAGEDIR, src, "names");
-
-	snprintf(key, sizeof(key), "%17s#%hhu", dst, dst_type);
-
-	str = textfile_get(filename, key);
-	if (str != NULL)
-		goto done;
-
-	/* Try old format (address only) */
-	key[17] = '\0';
-
-	str = textfile_get(filename, key);
-	if (str == NULL)
-		return -ENOENT;
-
-done:
-	len = strlen(str);
-	if (len > HCI_MAX_NAME_LENGTH)
-		str[HCI_MAX_NAME_LENGTH] = '\0';
-	strcpy(name, str);
-
-	free(str);
-
-	return 0;
-}
-
-int write_lastseen_info(const bdaddr_t *local, const bdaddr_t *peer,
-					uint8_t peer_type, struct tm *tm)
-{
-	char filename[PATH_MAX + 1], key[20], str[24];
-
-	memset(str, 0, sizeof(str));
-	strftime(str, sizeof(str), "%Y-%m-%d %H:%M:%S %Z", tm);
-
-	create_filename(filename, PATH_MAX, local, "lastseen");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	ba2str(peer, key);
-	sprintf(&key[17], "#%hhu", peer_type);
-
-	return textfile_put(filename, key, str);
-}
-
 int write_lastused_info(const bdaddr_t *local, const bdaddr_t *peer,
 					uint8_t peer_type, struct tm *tm)
 {
@@ -471,82 +243,6 @@ int write_lastused_info(const bdaddr_t *local, const bdaddr_t *peer,
 	return textfile_put(filename, key, str);
 }
 
-int write_link_key(const bdaddr_t *local, const bdaddr_t *peer,
-					uint8_t peer_type, unsigned char *key,
-					uint8_t type, int length)
-{
-	char filename[PATH_MAX + 1], addr[20], str[38];
-	int i;
-
-	memset(str, 0, sizeof(str));
-	for (i = 0; i < 16; i++)
-		sprintf(str + (i * 2), "%2.2X", key[i]);
-	sprintf(str + 32, " %d %d", type, length);
-
-	create_filename(filename, PATH_MAX, local, "linkkeys");
-
-	create_file(filename, S_IRUSR | S_IWUSR);
-
-	ba2str(peer, addr);
-	sprintf(&addr[17], "#%hhu", peer_type);
-
-	if (length < 0) {
-		char *tmp = textfile_get(filename, addr);
-		if (tmp) {
-			if (strlen(tmp) > 34)
-				memcpy(str + 34, tmp + 34, 3);
-			free(tmp);
-		}
-	}
-
-	return textfile_put(filename, addr, str);
-}
-
-int read_link_key(const bdaddr_t *local, const bdaddr_t *peer,
-					uint8_t peer_type, unsigned char *key,
-					uint8_t *type)
-{
-	char filename[PATH_MAX + 1], addr[20], tmp[3], *str;
-	int i;
-
-	create_filename(filename, PATH_MAX, local, "linkkeys");
-
-	ba2str(peer, addr);
-	sprintf(&addr[17], "#%hhu", peer_type);
-
-	str = textfile_get(filename, addr);
-	if (str != NULL)
-		goto done;
-
-	/* Try old format (address only) */
-	addr[17] = '\0';
-
-	str = textfile_get(filename, addr);
-	if (!str)
-		return -ENOENT;
-
-done:
-	if (!key) {
-		free(str);
-		return 0;
-	}
-
-	memset(tmp, 0, sizeof(tmp));
-	for (i = 0; i < 16; i++) {
-		memcpy(tmp, str + (i * 2), 2);
-		key[i] = (uint8_t) strtol(tmp, NULL, 16);
-	}
-
-	if (type) {
-		memcpy(tmp, str + 33, 2);
-		*type = (uint8_t) strtol(tmp, NULL, 10);
-	}
-
-	free(str);
-
-	return 0;
-}
-
 ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin)
 {
 	char filename[PATH_MAX + 1], addr[18], *str;
@@ -567,49 +263,6 @@ ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin)
 	return len;
 }
 
-int write_trust(const char *src, const char *addr, uint8_t addr_type,
-							gboolean trust)
-{
-	char filename[PATH_MAX + 1], key[20];
-
-	create_name(filename, PATH_MAX, STORAGEDIR, src, "trusts");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	snprintf(key, sizeof(key), "%17s#%hhu", addr, addr_type);
-
-	if (trust == FALSE)
-		return textfile_casedel(filename, key);
-
-	return textfile_caseput(filename, key, GLOBAL_TRUST);
-}
-
-gboolean read_trust(const bdaddr_t *local, const char *addr, uint8_t addr_type)
-{
-	char filename[PATH_MAX + 1], key[20], *str;
-	gboolean ret;
-
-	create_filename(filename, PATH_MAX, local, "trusts");
-
-	snprintf(key, sizeof(key), "%17s#%hhu", addr, addr_type);
-
-	str = textfile_caseget(filename, key);
-	if (str == NULL)
-		/* Try old format (address only) */
-		str = textfile_caseget(filename, addr);
-
-	if (str == NULL)
-		return FALSE;
-
-	if (strcmp(str, GLOBAL_TRUST) == 0)
-		ret = TRUE;
-	else
-		ret = FALSE;
-
-	free(str);
-	return ret;
-}
-
 int write_device_profiles(const bdaddr_t *src, const bdaddr_t *dst,
 					uint8_t dst_type, const char *profiles)
 {
@@ -847,167 +500,6 @@ sdp_record_t *find_record_in_list(sdp_list_t *recs, const char *uuid)
 	return NULL;
 }
 
-int store_device_id(const gchar *src, const gchar *dst, uint8_t dst_type,
-				const uint16_t source, const uint16_t vendor,
-				const uint16_t product, const uint16_t version)
-{
-	char filename[PATH_MAX + 1], key[20], str[20];
-
-	create_name(filename, PATH_MAX, STORAGEDIR, src, "did");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	snprintf(key, sizeof(key), "%17s#%hhu", dst, dst_type);
-
-	snprintf(str, sizeof(str), "%04X %04X %04X %04X", source,
-						vendor, product, version);
-
-	return textfile_put(filename, key, str);
-}
-
-static int read_device_id_from_did(const gchar *src, const gchar *dst,
-				   uint8_t dst_type, uint16_t *source,
-				   uint16_t *vendor, uint16_t *product,
-							uint16_t *version)
-{
-	char filename[PATH_MAX + 1];
-	char key[20], *str, *vendor_str, *product_str, *version_str;
-
-	create_name(filename, PATH_MAX, STORAGEDIR, src, "did");
-
-	snprintf(key, sizeof(key), "%17s#%hhu", dst, dst_type);
-
-	str = textfile_get(filename, key);
-	if (str != NULL)
-		goto done;
-
-	/* Try old format (address only) */
-	str = textfile_get(filename, dst);
-	if (!str)
-		return -ENOENT;
-
-done:
-	vendor_str = strchr(str, ' ');
-	if (!vendor_str) {
-		free(str);
-		return -ENOENT;
-	}
-	*(vendor_str++) = 0;
-
-	product_str = strchr(vendor_str, ' ');
-	if (!product_str) {
-		free(str);
-		return -ENOENT;
-	}
-	*(product_str++) = 0;
-
-	version_str = strchr(product_str, ' ');
-	if (!version_str) {
-		free(str);
-		return -ENOENT;
-	}
-	*(version_str++) = 0;
-
-	if (source)
-		*source = (uint16_t) strtol(str, NULL, 16);
-	if (vendor)
-		*vendor = (uint16_t) strtol(vendor_str, NULL, 16);
-	if (product)
-		*product = (uint16_t) strtol(product_str, NULL, 16);
-	if (version)
-		*version = (uint16_t) strtol(version_str, NULL, 16);
-
-	free(str);
-
-	return 0;
-}
-
-int read_device_id(const gchar *srcaddr, const gchar *dstaddr,
-		   uint8_t dst_type, uint16_t *source, uint16_t *vendor,
-					uint16_t *product, uint16_t *version)
-{
-	uint16_t lsource, lvendor, lproduct, lversion;
-	sdp_list_t *recs;
-	sdp_record_t *rec;
-	bdaddr_t src, dst;
-	int err;
-
-	err = read_device_id_from_did(srcaddr, dstaddr, dst_type, &lsource,
-								vendor, product,
-								version);
-	if (!err) {
-		if (lsource == 0xffff)
-			err = -ENOENT;
-
-		return err;
-	}
-
-	str2ba(srcaddr, &src);
-	str2ba(dstaddr, &dst);
-
-	recs = read_records(&src, &dst);
-	rec = find_record_in_list(recs, PNP_UUID);
-
-	if (rec) {
-		sdp_data_t *pdlist;
-
-		pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID_SOURCE);
-		lsource = pdlist ? pdlist->val.uint16 : 0x0000;
-
-		pdlist = sdp_data_get(rec, SDP_ATTR_VENDOR_ID);
-		lvendor = pdlist ? pdlist->val.uint16 : 0x0000;
-
-		pdlist = sdp_data_get(rec, SDP_ATTR_PRODUCT_ID);
-		lproduct = pdlist ? pdlist->val.uint16 : 0x0000;
-
-		pdlist = sdp_data_get(rec, SDP_ATTR_VERSION);
-		lversion = pdlist ? pdlist->val.uint16 : 0x0000;
-
-		err = 0;
-	}
-
-	sdp_list_free(recs, (sdp_free_func_t)sdp_record_free);
-
-	if (err) {
-		/* FIXME: We should try EIR data if we have it, too */
-
-		/* If we don't have the data, we don't want to go through the
-		 * above search every time. */
-		lsource = 0xffff;
-		lvendor = 0x0000;
-		lproduct = 0x0000;
-		lversion = 0x0000;
-	}
-
-	store_device_id(srcaddr, dstaddr, dst_type, lsource, lvendor,
-							lproduct, lversion);
-
-	if (err)
-		return err;
-
-	if (source)
-		*source = lsource;
-	if (vendor)
-		*vendor = lvendor;
-	if (product)
-		*product = lproduct;
-	if (version)
-		*version = lversion;
-
-	return 0;
-}
-
-int write_device_pairable(const bdaddr_t *bdaddr, gboolean mode)
-{
-	char filename[PATH_MAX + 1];
-
-	create_filename(filename, PATH_MAX, bdaddr, "config");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	return textfile_put(filename, "pairable", mode ? "yes" : "no");
-}
-
 int read_device_pairable(const bdaddr_t *bdaddr, gboolean *mode)
 {
 	char filename[PATH_MAX + 1], *str;
@@ -1025,51 +517,6 @@ int read_device_pairable(const bdaddr_t *bdaddr, gboolean *mode)
 	return 0;
 }
 
-gboolean read_blocked(const bdaddr_t *local, const bdaddr_t *remote,
-							uint8_t remote_type)
-{
-	char filename[PATH_MAX + 1], *str, key[20];
-
-	create_filename(filename, PATH_MAX, local, "blocked");
-
-	ba2str(remote, key);
-	sprintf(&key[17], "#%hhu", remote_type);
-
-	str = textfile_caseget(filename, key);
-	if (str != NULL)
-		goto done;
-
-	/* Try old format (address only) */
-	key[17] = '\0';
-
-	str = textfile_caseget(filename, key);
-	if (str == NULL)
-		return FALSE;
-
-done:
-	free(str);
-
-	return TRUE;
-}
-
-int write_blocked(const bdaddr_t *local, const bdaddr_t *remote,
-				uint8_t remote_type, gboolean blocked)
-{
-	char filename[PATH_MAX + 1], key[20];
-
-	create_filename(filename, PATH_MAX, local, "blocked");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	ba2str(remote, key);
-	sprintf(&key[17], "#%hhu", remote_type);
-
-	if (blocked == FALSE)
-		return textfile_casedel(filename, key);
-
-	return textfile_caseput(filename, key, "");
-}
-
 int write_device_services(const bdaddr_t *sba, const bdaddr_t *dba,
 			  uint8_t bdaddr_type, const char *services)
 {
@@ -1265,40 +712,3 @@ void delete_device_ccc(const bdaddr_t *local, const bdaddr_t *peer)
 	create_filename(filename, PATH_MAX, local, "ccc");
 	delete_by_pattern(filename, addr);
 }
-
-int write_longtermkeys(const bdaddr_t *local, const bdaddr_t *peer,
-					uint8_t bdaddr_type, const char *key)
-{
-	char filename[PATH_MAX + 1], addr[20];
-
-	if (!key)
-		return -EINVAL;
-
-	create_filename(filename, PATH_MAX, local, "longtermkeys");
-
-	create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
-
-	ba2str(peer, addr);
-	sprintf(&addr[17], "#%hhu", bdaddr_type);
-
-	return textfile_put(filename, addr, key);
-}
-
-gboolean has_longtermkeys(const bdaddr_t *local, const bdaddr_t *peer,
-							uint8_t bdaddr_type)
-{
-	char filename[PATH_MAX + 1], key[20], *str;
-
-	create_filename(filename, PATH_MAX, local, "longtermkeys");
-
-	ba2str(peer, key);
-	sprintf(&key[17], "#%hhu", bdaddr_type);
-
-	str = textfile_caseget(filename, key);
-	if (str) {
-		free(str);
-		return TRUE;
-	}
-
-	return FALSE;
-}
diff --git a/src/storage.h b/src/storage.h
index e334828..c8ae6b0 100644
--- a/src/storage.h
+++ b/src/storage.h
@@ -23,47 +23,19 @@
 
 #include "textfile.h"
 
-int read_device_alias(const char *src, const char *dst, uint8_t dst_type,
-						char *alias, size_t size);
-int write_device_alias(const char *src, const char *dst, uint8_t dst_type,
-							const char *alias);
-int write_discoverable_timeout(const bdaddr_t *bdaddr, int timeout);
 int read_discoverable_timeout(const char *src, int *timeout);
-int write_pairable_timeout(const bdaddr_t *bdaddr, int timeout);
 int read_pairable_timeout(const char *src, int *timeout);
-int write_device_mode(const bdaddr_t *bdaddr, const char *mode);
 int read_device_mode(const char *src, char *mode, int length);
 int read_on_mode(const char *src, char *mode, int length);
-int write_local_name(const bdaddr_t *bdaddr, const char *name);
 int read_local_name(const bdaddr_t *bdaddr, char *name);
-int write_local_class(const bdaddr_t *bdaddr, uint8_t *class);
 int read_local_class(const bdaddr_t *bdaddr, uint8_t *class);
 int write_remote_appearance(const bdaddr_t *local, const bdaddr_t *peer,
 				uint8_t bdaddr_type, uint16_t appearance);
 int read_remote_appearance(const bdaddr_t *local, const bdaddr_t *peer,
 				uint8_t bdaddr_type, uint16_t *appearance);
-int write_remote_class(const bdaddr_t *local, const bdaddr_t *peer,
-							uint32_t class);
-int read_remote_class(const bdaddr_t *local, const bdaddr_t *peer,
-							uint32_t *class);
-int write_device_name(const bdaddr_t *local, const bdaddr_t *peer,
-					uint8_t peer_type, const char *name);
-int read_device_name(const char *src, const char *dst, uint8_t dst_type,
-								char *name);
-int write_lastseen_info(const bdaddr_t *local, const bdaddr_t *peer,
-					uint8_t peer_type, struct tm *tm);
 int write_lastused_info(const bdaddr_t *local, const bdaddr_t *peer,
 					uint8_t peer_type, struct tm *tm);
-int write_link_key(const bdaddr_t *local, const bdaddr_t *peer,
-					uint8_t peer_type, unsigned char *key,
-					uint8_t type, int length);
-int read_link_key(const bdaddr_t *local, const bdaddr_t *peer,
-			uint8_t peer_type, unsigned char *key, uint8_t *type);
 ssize_t read_pin_code(const bdaddr_t *local, const bdaddr_t *peer, char *pin);
-gboolean read_trust(const bdaddr_t *local, const char *addr,
-						uint8_t addr_type);
-int write_trust(const char *src, const char *addr, uint8_t addr_type,
-							gboolean trust);
 int write_device_profiles(const bdaddr_t *src, const bdaddr_t *dst,
 				uint8_t dst_type, const char *profiles);
 int delete_entry(const bdaddr_t *src, const char *storage, const bdaddr_t *dst,
@@ -79,18 +51,7 @@ void delete_all_records(const bdaddr_t *src, const bdaddr_t *dst,
 							uint8_t dst_type);
 sdp_list_t *read_records(const bdaddr_t *src, const bdaddr_t *dst);
 sdp_record_t *find_record_in_list(sdp_list_t *recs, const char *uuid);
-int store_device_id(const gchar *src, const gchar *dst, uint8_t dst_type,
-				const uint16_t source, const uint16_t vendor,
-				const uint16_t product, const uint16_t version);
-int read_device_id(const gchar *src, const gchar *dst, uint8_t dst_type,
-					uint16_t *source, uint16_t *vendor,
-					uint16_t *product, uint16_t *version);
-int write_device_pairable(const bdaddr_t *local, gboolean mode);
 int read_device_pairable(const bdaddr_t *local, gboolean *mode);
-gboolean read_blocked(const bdaddr_t *local, const bdaddr_t *remote,
-							uint8_t remote_type);
-int write_blocked(const bdaddr_t *local, const bdaddr_t *remote,
-				uint8_t remote_type, gboolean blocked);
 int write_device_services(const bdaddr_t *sba, const bdaddr_t *dba,
 				uint8_t bdaddr_type, const char *services);
 int delete_device_service(const bdaddr_t *sba, const bdaddr_t *dba,
@@ -112,7 +73,3 @@ int write_device_ccc(const bdaddr_t *local, const bdaddr_t *peer,
 					uint8_t bdaddr_type, uint16_t handle,
 					uint16_t value);
 void delete_device_ccc(const bdaddr_t *local, const bdaddr_t *peer);
-int write_longtermkeys(const bdaddr_t *local, const bdaddr_t *peer,
-					uint8_t bdaddr_type, const char *key);
-gboolean has_longtermkeys(const bdaddr_t *local, const bdaddr_t *peer,
-							uint8_t bdaddr_type);
-- 
1.7.9.5


^ permalink raw reply related

* Re: [RFC 12/16] Bluetooth: Use abstract chan->data in comparison
From: Andrei Emeltchenko @ 2012-12-12  8:20 UTC (permalink / raw)
  To: Gustavo Padovan; +Cc: linux-bluetooth, Gustavo Padovan
In-Reply-To: <1355285624-25811-13-git-send-email-gustavo@padovan.org>

Hi Gustavo,

On Wed, Dec 12, 2012 at 02:13:40AM -0200, Gustavo Padovan wrote:
> From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> 
> If the L2CAP user is l2cap_sock.c chan->data is a pointer to the l2cap
> socket so chan->sk and chan->data are the same thing. Then we can just
> compare with chan->data instead.
> 
> Non-socket users will have skb->sk = NULL, thus this change does not
> interfere in other users.
> 
> Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
> ---
>  net/bluetooth/l2cap_core.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
> 
> diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
> index 934ac1b..92936db 100644
> --- a/net/bluetooth/l2cap_core.c
> +++ b/net/bluetooth/l2cap_core.c
> @@ -2682,12 +2682,11 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
>  	mutex_lock(&conn->chan_lock);
>  
>  	list_for_each_entry(chan, &conn->chan_l, list) {
> -		struct sock *sk = chan->sk;
>  		if (chan->chan_type != L2CAP_CHAN_RAW)
>  			continue;
>  
>  		/* Don't send frame to the socket it came from */
> -		if (skb->sk == sk)
> +		if (skb->sk && skb->sk == chan->data)

In the other patch you delete chan->sk pointer and then we have only
chan->data which points to sk. What is the reason for that? This would
confuse people reading chan->data guessing what the hell is this.

I really think we can leave chan->sk if it is needed and it is better to
remove chan->data.

Best regards 
Andrei Emeltchenko 


^ permalink raw reply

* Re: [BLE] org.bluez.Device1.Connect() returns org.bluez.Error.NotAvailable
From: Johan Hedberg @ 2012-12-12  7:52 UTC (permalink / raw)
  To: Ting Chou; +Cc: linux-bluetooth@vger.kernel.org
In-Reply-To: <ADCBF04BB97EBF4AAE65663F8478B61CA99E65AB92@Luna.iaSolution.net>

Hi Ting,

On Wed, Dec 12, 2012, Ting Chou wrote:
> I Found
> -------
> 
> - I checked /var/log/syslog and src/device.c, and found connect_profiles() is
>   called twice at the first time calling org.bluez.Device.Connect():
> 
>   - 1st time
>     dev->svc_resolved==FALSE, device_resolve_svc() is invoked.
> 
>   - 2nd time
>     dev->svc_resolved==TRUE
>     In the for loop of iterating device profiles, there're two profiles:
> 
>       a) p->auto_connect==FALSE, p->name==deviceinfo, p->local_uuid==NULL
>       b) p->auto_connect==FALSE, p->name==Health Thermometer GATT driver, p->local_uuid==NULL
> 
>     Since none of them have auto_connect TRUE, dev->pending==NULL, and
>     btd_error_not_available() is called.
> 
> - I tried org.bluez.Device1.ConnectProfile() as well, but since all the profiles
>   have local_uuid NULL, find_connectable_profile() return NULL and
>   btd_error_invalid_args() is called.

It's not actually local_uuid that is so important but that p->connect is
set. Also, it'd make much more sense to pass the remote UUID to
ConnectProfile than the local one and we'll still do this change before
releasing 5.0. The main thing that needs to be done before that is to
convert profile->remote_uuids list to a single profile->remote_uuid
which is a bit of work since some profiles still declare multiple UUIDs.

So far no LE profile is hooked up to Device.Connect and I'm not sure
exactly how that should be done since LE device are connected through
the general connection establishment procedure which requires scanning
first. Since we already have Device.Pair doing the same as
CreatePairedDevice in BlueZ 4 (and this should work btw, did you try
it?) maybe Device.Connect should be roughly the same for LE devices as
Adapter.CreateDevice is in BlueZ 4? For BR/EDR devices it already serves
this purpose. The main question is what should be done if Device.Connect
is called subsequent times as bluetoothd should anyway already be doing
passive scanning and trying to connect to devices that have supported
profiles.

Johan

^ permalink raw reply

* [RFC 16/16] Bluetooth: Remove sk member from struct l2cap_chan
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Now that the removal of socket usage from l2cap_core.c is done we can
remove sk from struct l2cap_chan since we do not use it anywhere anymore.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 include/net/bluetooth/l2cap.h | 2 --
 net/bluetooth/l2cap_sock.c    | 5 ++---
 2 files changed, 2 insertions(+), 5 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index b6bfbbd..2d18bcb 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -433,8 +433,6 @@ struct l2cap_seq_list {
 #define L2CAP_SEQ_LIST_TAIL	0x8000
 
 struct l2cap_chan {
-	struct sock *sk;
-
 	bdaddr_t	src;
 	bdaddr_t	dst;
 
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 1f80b9b..82b7d0a 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1100,11 +1100,12 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state, int e
 static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
 					       unsigned long len, int nb)
 {
+	struct sock *sk = chan->data;
 	struct sk_buff *skb;
 	int err;
 
 	l2cap_chan_unlock(chan);
-	skb = bt_skb_send_alloc(chan->sk, len, nb, &err);
+	skb = bt_skb_send_alloc(sk, len, nb, &err);
 	l2cap_chan_lock(chan);
 
 	if (!skb)
@@ -1292,8 +1293,6 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock,
 
 	l2cap_chan_hold(chan);
 
-	chan->sk = sk;
-
 	l2cap_pi(sk)->chan = chan;
 
 	return sk;
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 15/16] Bluetooth: Create l2cap->ops->set_shutdown()
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Isolates the code that sets the socket shutdown mask. This is the last
commit to remove the socket usage from l2cap_core.c

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 include/net/bluetooth/l2cap.h |  5 +++++
 net/bluetooth/a2mp.c          |  1 +
 net/bluetooth/l2cap_core.c    |  7 +------
 net/bluetooth/l2cap_sock.c    | 10 ++++++++++
 4 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 04dd8cd..b6bfbbd 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -557,6 +557,7 @@ struct l2cap_ops {
 	struct sk_buff		*(*alloc_skb) (struct l2cap_chan *chan,
 					       unsigned long len, int nb);
 	void			(*resume) (struct l2cap_chan *chan);
+	void			(*set_shutdown) (struct l2cap_chan *chan);
 };
 
 struct l2cap_conn {
@@ -795,6 +796,10 @@ static inline void l2cap_chan_no_resume(struct l2cap_chan *chan)
 {
 }
 
+static inline void l2cap_chan_no_set_shutdown(struct l2cap_chan *chan)
+{
+}
+
 extern bool disable_ertm;
 
 int l2cap_init_sockets(void);
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 23265d9..a4286b2 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -701,6 +701,7 @@ static struct l2cap_ops a2mp_chan_ops = {
 	.ready = l2cap_chan_no_ready,
 	.defer = l2cap_chan_no_defer,
 	.resume = l2cap_chan_no_resume,
+	.set_shutdown = l2cap_chan_no_set_shutdown,
 };
 
 static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a294422..7d3fed1 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3978,7 +3978,6 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
 	struct l2cap_disconn_rsp rsp;
 	u16 dcid, scid;
 	struct l2cap_chan *chan;
-	struct sock *sk;
 
 	scid = __le16_to_cpu(req->scid);
 	dcid = __le16_to_cpu(req->dcid);
@@ -3995,15 +3994,11 @@ static inline int l2cap_disconnect_req(struct l2cap_conn *conn,
 
 	l2cap_chan_lock(chan);
 
-	sk = chan->sk;
-
 	rsp.dcid = cpu_to_le16(chan->scid);
 	rsp.scid = cpu_to_le16(chan->dcid);
 	l2cap_send_cmd(conn, cmd->ident, L2CAP_DISCONN_RSP, sizeof(rsp), &rsp);
 
-	lock_sock(sk);
-	sk->sk_shutdown = SHUTDOWN_MASK;
-	release_sock(sk);
+	chan->ops->set_shutdown(chan);
 
 	l2cap_chan_hold(chan);
 	l2cap_chan_del(chan, ECONNRESET);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index f89e558..1f80b9b 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1158,6 +1158,15 @@ static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
 	release_sock(sk);
 }
 
+static void l2cap_sock_set_shutdown_cb(struct l2cap_chan *chan)
+{
+	struct sock *sk = chan->data;
+
+	lock_sock(sk);
+	sk->sk_shutdown = SHUTDOWN_MASK;
+	release_sock(sk);
+}
+
 static struct l2cap_ops l2cap_chan_ops = {
 	.name		= "L2CAP Socket Interface",
 	.new_connection	= l2cap_sock_new_connection_cb,
@@ -1169,6 +1178,7 @@ static struct l2cap_ops l2cap_chan_ops = {
 	.defer		= l2cap_sock_defer_cb,
 	.alloc_skb	= l2cap_sock_alloc_skb_cb,
 	.resume		= l2cap_sock_resume_cb,
+	.set_shutdown	= l2cap_sock_set_shutdown_cb,
 };
 
 static void l2cap_sock_destruct(struct sock *sk)
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 14/16] Bluetooth: Create l2cap->ops->resume()
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

resume() will isolate the code the code to get a socket back from the
suspended state when a security elevation happens.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 include/net/bluetooth/l2cap.h |  5 +++++
 net/bluetooth/a2mp.c          |  1 +
 net/bluetooth/l2cap_core.c    |  6 +-----
 net/bluetooth/l2cap_sock.c    | 13 +++++++++++++
 4 files changed, 20 insertions(+), 5 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 9673ef4..04dd8cd 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -556,6 +556,7 @@ struct l2cap_ops {
 	void			(*defer) (struct l2cap_chan *chan);
 	struct sk_buff		*(*alloc_skb) (struct l2cap_chan *chan,
 					       unsigned long len, int nb);
+	void			(*resume) (struct l2cap_chan *chan);
 };
 
 struct l2cap_conn {
@@ -790,6 +791,10 @@ static inline void l2cap_chan_no_defer(struct l2cap_chan *chan)
 {
 }
 
+static inline void l2cap_chan_no_resume(struct l2cap_chan *chan)
+{
+}
+
 extern bool disable_ertm;
 
 int l2cap_init_sockets(void);
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 2b6faae..23265d9 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -700,6 +700,7 @@ static struct l2cap_ops a2mp_chan_ops = {
 	.teardown = l2cap_chan_no_teardown,
 	.ready = l2cap_chan_no_ready,
 	.defer = l2cap_chan_no_defer,
+	.resume = l2cap_chan_no_resume,
 };
 
 static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn, bool locked)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 68faff8..a294422 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -6320,11 +6320,7 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 
 		if (!status && (chan->state == BT_CONNECTED ||
 				chan->state == BT_CONFIG)) {
-			struct sock *sk = chan->sk;
-
-			clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
-			sk->sk_state_change(sk);
-
+			chan->ops->resume(chan);
 			l2cap_check_encryption(chan, encrypt);
 			l2cap_chan_unlock(chan);
 			continue;
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 51fbc98..f89e558 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1146,6 +1146,18 @@ static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
 	release_sock(sk);
 }
 
+static void l2cap_sock_resume_cb(struct l2cap_chan *chan)
+{
+	struct sock *sk = chan->data;
+
+	lock_sock(sk);
+
+	clear_bit(BT_SK_SUSPEND, &bt_sk(sk)->flags);
+	sk->sk_state_change(sk);
+
+	release_sock(sk);
+}
+
 static struct l2cap_ops l2cap_chan_ops = {
 	.name		= "L2CAP Socket Interface",
 	.new_connection	= l2cap_sock_new_connection_cb,
@@ -1156,6 +1168,7 @@ static struct l2cap_ops l2cap_chan_ops = {
 	.ready		= l2cap_sock_ready_cb,
 	.defer		= l2cap_sock_defer_cb,
 	.alloc_skb	= l2cap_sock_alloc_skb_cb,
+	.resume		= l2cap_sock_resume_cb,
 };
 
 static void l2cap_sock_destruct(struct sock *sk)
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 13/16] Bluetooth: Move l2cap_wait_ack() to l2cap_sock.c
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

The wait_ack code has a heavy dependency on the socket data structures
and, as of now, it won't be worthless change it to use non-socket
structures as the only user of such feature is a socket.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 include/net/bluetooth/l2cap.h |  3 ++-
 net/bluetooth/l2cap_core.c    | 32 --------------------------------
 net/bluetooth/l2cap_sock.c    | 32 ++++++++++++++++++++++++++++++++
 3 files changed, 34 insertions(+), 33 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index b1cc286..9673ef4 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -758,6 +758,8 @@ static inline bool l2cap_clear_timer(struct l2cap_chan *chan,
 		msecs_to_jiffies(L2CAP_DEFAULT_ACK_TO));
 #define __clear_ack_timer(c) l2cap_clear_timer(c, &c->ack_timer)
 
+#define __missing_ack(c) (c->unacked_frames > 0 && c->conn)
+
 static inline int __seq_offset(struct l2cap_chan *chan, __u16 seq1, __u16 seq2)
 {
 	if (seq1 >= seq2)
@@ -794,7 +796,6 @@ int l2cap_init_sockets(void);
 void l2cap_cleanup_sockets(void);
 
 void __l2cap_connect_rsp_defer(struct l2cap_chan *chan);
-int __l2cap_wait_ack(struct sock *sk);
 
 int l2cap_add_psm(struct l2cap_chan *chan, bdaddr_t *src, __le16 psm);
 int l2cap_add_scid(struct l2cap_chan *chan,  __u16 scid);
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 92936db..68faff8 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1711,38 +1711,6 @@ done:
 	return err;
 }
 
-int __l2cap_wait_ack(struct sock *sk)
-{
-	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
-	DECLARE_WAITQUEUE(wait, current);
-	int err = 0;
-	int timeo = HZ/5;
-
-	add_wait_queue(sk_sleep(sk), &wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-	while (chan->unacked_frames > 0 && chan->conn) {
-		if (!timeo)
-			timeo = HZ/5;
-
-		if (signal_pending(current)) {
-			err = sock_intr_errno(timeo);
-			break;
-		}
-
-		release_sock(sk);
-		timeo = schedule_timeout(timeo);
-		lock_sock(sk);
-		set_current_state(TASK_INTERRUPTIBLE);
-
-		err = sock_error(sk);
-		if (err)
-			break;
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(sk_sleep(sk), &wait);
-	return err;
-}
-
 static void l2cap_monitor_timeout(struct work_struct *work)
 {
 	struct l2cap_chan *chan = container_of(work, struct l2cap_chan,
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index e4fcbde..51fbc98 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -853,6 +853,38 @@ static void l2cap_sock_kill(struct sock *sk)
 	sock_put(sk);
 }
 
+static int __l2cap_wait_ack(struct sock *sk)
+{
+	struct l2cap_chan *chan = l2cap_pi(sk)->chan;
+	DECLARE_WAITQUEUE(wait, current);
+	int err = 0;
+	int timeo = HZ/5;
+
+	add_wait_queue(sk_sleep(sk), &wait);
+	set_current_state(TASK_INTERRUPTIBLE);
+	while (__missing_ack(chan)) {
+		if (!timeo)
+			timeo = HZ/5;
+
+		if (signal_pending(current)) {
+			err = sock_intr_errno(timeo);
+			break;
+		}
+
+		release_sock(sk);
+		timeo = schedule_timeout(timeo);
+		lock_sock(sk);
+		set_current_state(TASK_INTERRUPTIBLE);
+
+		err = sock_error(sk);
+		if (err)
+			break;
+	}
+	set_current_state(TASK_RUNNING);
+	remove_wait_queue(sk_sleep(sk), &wait);
+	return err;
+}
+
 static int l2cap_sock_shutdown(struct socket *sock, int how)
 {
 	struct sock *sk = sock->sk;
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 12/16] Bluetooth: Use abstract chan->data in comparison
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

If the L2CAP user is l2cap_sock.c chan->data is a pointer to the l2cap
socket so chan->sk and chan->data are the same thing. Then we can just
compare with chan->data instead.

Non-socket users will have skb->sk = NULL, thus this change does not
interfere in other users.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 net/bluetooth/l2cap_core.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 934ac1b..92936db 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -2682,12 +2682,11 @@ static void l2cap_raw_recv(struct l2cap_conn *conn, struct sk_buff *skb)
 	mutex_lock(&conn->chan_lock);
 
 	list_for_each_entry(chan, &conn->chan_l, list) {
-		struct sock *sk = chan->sk;
 		if (chan->chan_type != L2CAP_CHAN_RAW)
 			continue;
 
 		/* Don't send frame to the socket it came from */
-		if (skb->sk == sk)
+		if (skb->sk && skb->sk == chan->data)
 			continue;
 		nskb = skb_clone(skb, GFP_KERNEL);
 		if (!nskb)
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 11/16] Bluetooth: remove parent socket usage from l2cap_core.c
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Since we do not touch the parent sock in l2cap_core.c anymore we don't
need to lock it there anymore. That lock was replaced by the
l2cap_chan_lock and inside the new_connection() call for l2cap_sock.c the
parent lock is locked, so the operations that uses it can be performed
safely.

The l2cap_chan_lock give us the needed protection to handle the incoming
connections.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 net/bluetooth/l2cap_core.c | 16 ++++------------
 net/bluetooth/l2cap_sock.c |  4 ++++
 2 files changed, 8 insertions(+), 12 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a69976b..934ac1b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1315,7 +1315,6 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
 
 static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 {
-	struct sock *parent;
 	struct l2cap_chan *chan, *pchan;
 
 	BT_DBG("");
@@ -1326,9 +1325,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 	if (!pchan)
 		return;
 
-	parent = pchan->sk;
-
-	lock_sock(parent);
+	l2cap_chan_lock(pchan);
 
 	chan = pchan->ops->new_connection(pchan);
 	if (!chan)
@@ -1345,7 +1342,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 	l2cap_chan_ready(chan);
 
 clean:
-	release_sock(parent);
+	l2cap_chan_unlock(pchan);
 }
 
 static void l2cap_conn_ready(struct l2cap_conn *conn)
@@ -3567,7 +3564,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
 	struct l2cap_conn_req *req = (struct l2cap_conn_req *) data;
 	struct l2cap_conn_rsp rsp;
 	struct l2cap_chan *chan = NULL, *pchan;
-	struct sock *parent, *sk = NULL;
 	int result, status = L2CAP_CS_NO_INFO;
 
 	u16 dcid = 0, scid = __le16_to_cpu(req->scid);
@@ -3582,10 +3578,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
 		goto sendresp;
 	}
 
-	parent = pchan->sk;
-
 	mutex_lock(&conn->chan_lock);
-	lock_sock(parent);
+	l2cap_chan_lock(pchan);
 
 	/* Check if the ACL is secure enough (if not SDP) */
 	if (psm != __constant_cpu_to_le16(L2CAP_PSM_SDP) &&
@@ -3605,8 +3599,6 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
 	if (!chan)
 		goto response;
 
-	sk = chan->sk;
-
 	hci_conn_hold(conn->hcon);
 
 	bacpy(&chan->src, conn->src);
@@ -3656,7 +3648,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
 	}
 
 response:
-	release_sock(parent);
+	l2cap_chan_unlock(pchan);
 	mutex_unlock(&conn->chan_lock);
 
 sendresp:
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 4ab3adc..e4fcbde 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -943,6 +943,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
 {
 	struct sock *sk, *parent = chan->data;
 
+	lock_sock(parent);
+
 	/* Check for backlog size */
 	if (sk_acceptq_is_full(parent)) {
 		BT_DBG("backlog full %d", parent->sk_ack_backlog);
@@ -960,6 +962,8 @@ static struct l2cap_chan *l2cap_sock_new_connection_cb(struct l2cap_chan *chan)
 
 	bt_accept_enqueue(parent, sk);
 
+	release_sock(parent);
+
 	return l2cap_pi(sk)->chan;
 }
 
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 10/16] Bluetooth: Remove socket lock from state_change() in l2cap_core
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

This simplifies a lot the state change handling inside l2cap_core.c,
we got rid of __l2cap_state_change() and l2cap_state_change() doesn't lock
the socket anymore, instead the socket is locked inside the ops user code
in l2cap_sock.c.

In some places we were not using the locked version, and now we are using
it. There is no side effect in locking the socket in these places.

Handle the operation of lock the socket to ops user benefit A2MP, since
there is no socket lock there it doesn't need any special function in
l2cap work without touching socket locks.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 net/bluetooth/l2cap_core.c | 32 +++++++-------------------------
 net/bluetooth/l2cap_sock.c |  4 ++++
 2 files changed, 11 insertions(+), 25 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 3d96c3b..a69976b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -210,7 +210,7 @@ static u16 l2cap_alloc_cid(struct l2cap_conn *conn)
 	return 0;
 }
 
-static void __l2cap_state_change(struct l2cap_chan *chan, int state)
+static void l2cap_state_change(struct l2cap_chan *chan, int state)
 {
 	BT_DBG("chan %p %s -> %s", chan, state_to_string(chan->state),
 	       state_to_string(state));
@@ -219,33 +219,16 @@ static void __l2cap_state_change(struct l2cap_chan *chan, int state)
 	chan->ops->state_change(chan, state, 0);
 }
 
-static void l2cap_state_change(struct l2cap_chan *chan, int state)
-{
-	struct sock *sk = chan->sk;
-
-	lock_sock(sk);
-	__l2cap_state_change(chan, state);
-	release_sock(sk);
-}
-
 static void l2cap_state_change_and_error(struct l2cap_chan *chan, int state,
 					 int err)
 {
-	struct sock *sk = chan->sk;
-
-	lock_sock(sk);
 	chan->state = state;
 	chan->ops->state_change(chan, state, err);
-	release_sock(sk);
 }
 
 static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
 {
-	struct sock *sk = chan->sk;
-
-	lock_sock(sk);
 	chan->ops->state_change(chan, chan->state, 0);
-	release_sock(sk);
 }
 
 static void __set_retrans_timer(struct l2cap_chan *chan)
@@ -1219,7 +1202,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
 	mutex_lock(&conn->chan_lock);
 
 	list_for_each_entry_safe(chan, tmp, &conn->chan_l, list) {
-		struct sock *sk = chan->sk;
 
 		l2cap_chan_lock(chan);
 
@@ -3644,7 +3626,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
 	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
 		if (l2cap_chan_check_security(chan)) {
 			if (test_bit(CONN_DEFER_SETUP, &chan->conn_state)) {
-				__l2cap_state_change(chan, BT_CONNECT2);
+				l2cap_state_change(chan, BT_CONNECT2);
 				result = L2CAP_CR_PEND;
 				status = L2CAP_CS_AUTHOR_PEND;
 				chan->ops->defer(chan);
@@ -3654,21 +3636,21 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
 				 * physical link is up.
 				 */
 				if (amp_id) {
-					__l2cap_state_change(chan, BT_CONNECT2);
+					l2cap_state_change(chan, BT_CONNECT2);
 					result = L2CAP_CR_PEND;
 				} else {
-					__l2cap_state_change(chan, BT_CONFIG);
+					l2cap_state_change(chan, BT_CONFIG);
 					result = L2CAP_CR_SUCCESS;
 				}
 				status = L2CAP_CS_NO_INFO;
 			}
 		} else {
-			__l2cap_state_change(chan, BT_CONNECT2);
+			l2cap_state_change(chan, BT_CONNECT2);
 			result = L2CAP_CR_PEND;
 			status = L2CAP_CS_AUTHEN_PEND;
 		}
 	} else {
-		__l2cap_state_change(chan, BT_CONNECT2);
+		l2cap_state_change(chan, BT_CONNECT2);
 		result = L2CAP_CR_PEND;
 		status = L2CAP_CS_NO_INFO;
 	}
@@ -4547,7 +4529,7 @@ static void l2cap_do_create(struct l2cap_chan *chan, int result,
 			       sizeof(rsp), &rsp);
 
 		if (result == L2CAP_CR_SUCCESS) {
-			__l2cap_state_change(chan, BT_CONFIG);
+			l2cap_state_change(chan, BT_CONFIG);
 			set_bit(CONF_REQ_SENT, &chan->conf_state);
 			l2cap_send_cmd(chan->conn, l2cap_get_ident(chan->conn),
 				       L2CAP_CONF_REQ,
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index c8bbe4e..4ab3adc 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1051,10 +1051,14 @@ static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state, int e
 {
 	struct sock *sk = chan->data;
 
+	lock_sock(sk);
+
 	sk->sk_state = state;
 
 	if (err)
 		sk->sk_err = err;
+
+	release_sock(sk);
 }
 
 static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 09/16] Bluetooth: lock socket in defer_cb call
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Since we removed the lock around the ops->defer() call inside
l2cap_core.c we need now to protect the defer_cb call.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 net/bluetooth/l2cap_sock.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)

diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index a6ecf58..c8bbe4e 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1095,11 +1095,15 @@ static void l2cap_sock_ready_cb(struct l2cap_chan *chan)
 
 static void l2cap_sock_defer_cb(struct l2cap_chan *chan)
 {
-	struct sock *sk = chan->data;
-	struct sock *parent = bt_sk(sk)->parent;
+	struct sock *parent, *sk = chan->data;
+
+	lock_sock(sk);
 
+	parent = bt_sk(sk)->parent;
 	if (parent)
 		parent->sk_data_ready(parent, 0);
+
+	release_sock(sk);
 }
 
 static struct l2cap_ops l2cap_chan_ops = {
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 08/16] Bluetooth: Improving locking in l2cap_conn_start()
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Since we don't read bt_sk(sk) in here anymore we can remove the lock from
the block and only use it when calling l2cap_state_change().

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 net/bluetooth/l2cap_core.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index aacf202..3d96c3b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1252,7 +1252,6 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
 			rsp.dcid = cpu_to_le16(chan->scid);
 
 			if (l2cap_chan_check_security(chan)) {
-				lock_sock(sk);
 				if (test_bit(CONN_DEFER_SETUP,
 					     &chan->conn_state)) {
 					rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
@@ -1260,11 +1259,10 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
 					chan->ops->defer(chan);
 
 				} else {
-					__l2cap_state_change(chan, BT_CONFIG);
+					l2cap_state_change(chan, BT_CONFIG);
 					rsp.result = __constant_cpu_to_le16(L2CAP_CR_SUCCESS);
 					rsp.status = __constant_cpu_to_le16(L2CAP_CS_NO_INFO);
 				}
-				release_sock(sk);
 			} else {
 				rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
 				rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHEN_PEND);
@@ -6398,12 +6396,9 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 				__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
 			}
 		} else if (chan->state == BT_CONNECT2) {
-			struct sock *sk = chan->sk;
 			struct l2cap_conn_rsp rsp;
 			__u16 res, stat;
 
-			lock_sock(sk);
-
 			if (!status) {
 				if (test_bit(CONN_DEFER_SETUP,
 					     &chan->conn_state)) {
@@ -6411,19 +6406,17 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 					stat = L2CAP_CS_AUTHOR_PEND;
 					chan->ops->defer(chan);
 				} else {
-					__l2cap_state_change(chan, BT_CONFIG);
+					l2cap_state_change(chan, BT_CONFIG);
 					res = L2CAP_CR_SUCCESS;
 					stat = L2CAP_CS_NO_INFO;
 				}
 			} else {
-				__l2cap_state_change(chan, BT_DISCONN);
+				l2cap_state_change(chan, BT_DISCONN);
 				__set_chan_timer(chan, L2CAP_DISC_TIMEOUT);
 				res = L2CAP_CR_SEC_BLOCK;
 				stat = L2CAP_CS_NO_INFO;
 			}
 
-			release_sock(sk);
-
 			rsp.scid   = cpu_to_le16(chan->dcid);
 			rsp.dcid   = cpu_to_le16(chan->scid);
 			rsp.result = cpu_to_le16(res);
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 07/16] Bluetooth: duplicate DEFER_SETUP flag on l2cap_chan
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Now l2cap_chan also has the DEFER_SETUP flag, so we don't need to access
the bt_sk(sk) to read this flag inside l2cap_core.c. We need to kep it
duplicate since it is used in Bluetooth socket code as well.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 include/net/bluetooth/l2cap.h |  1 +
 net/bluetooth/l2cap_core.c    | 16 +++++++---------
 net/bluetooth/l2cap_sock.c    |  7 +++++--
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index c361c47..b1cc286 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -636,6 +636,7 @@ enum {
 	CONN_REJ_ACT,
 	CONN_SEND_FBIT,
 	CONN_RNR_SENT,
+	CONN_DEFER_SETUP,
 };
 
 /* Definitions for flags in l2cap_chan */
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d3af9ddd..aacf202 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -620,10 +620,8 @@ void l2cap_chan_del(struct l2cap_chan *chan, int err)
 void l2cap_chan_close(struct l2cap_chan *chan, int reason)
 {
 	struct l2cap_conn *conn = chan->conn;
-	struct sock *sk = chan->sk;
 
-	BT_DBG("chan %p state %s sk %p", chan, state_to_string(chan->state),
-	       sk);
+	BT_DBG("chan %p state %s", chan, state_to_string(chan->state));
 
 	switch (chan->state) {
 	case BT_LISTEN:
@@ -646,7 +644,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
 			struct l2cap_conn_rsp rsp;
 			__u16 result;
 
-			if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags))
+			if (test_bit(CONN_DEFER_SETUP, &chan->conn_state))
 				result = L2CAP_CR_SEC_BLOCK;
 			else
 				result = L2CAP_CR_BAD_PSM;
@@ -1255,8 +1253,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
 
 			if (l2cap_chan_check_security(chan)) {
 				lock_sock(sk);
-				if (test_bit(BT_SK_DEFER_SETUP,
-					     &bt_sk(sk)->flags)) {
+				if (test_bit(CONN_DEFER_SETUP,
+					     &chan->conn_state)) {
 					rsp.result = __constant_cpu_to_le16(L2CAP_CR_PEND);
 					rsp.status = __constant_cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
 					chan->ops->defer(chan);
@@ -3647,7 +3645,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
 
 	if (conn->info_state & L2CAP_INFO_FEAT_MASK_REQ_DONE) {
 		if (l2cap_chan_check_security(chan)) {
-			if (test_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags)) {
+			if (test_bit(CONN_DEFER_SETUP, &chan->conn_state)) {
 				__l2cap_state_change(chan, BT_CONNECT2);
 				result = L2CAP_CR_PEND;
 				status = L2CAP_CS_AUTHOR_PEND;
@@ -6407,8 +6405,8 @@ int l2cap_security_cfm(struct hci_conn *hcon, u8 status, u8 encrypt)
 			lock_sock(sk);
 
 			if (!status) {
-				if (test_bit(BT_SK_DEFER_SETUP,
-					     &bt_sk(sk)->flags)) {
+				if (test_bit(CONN_DEFER_SETUP,
+					     &chan->conn_state)) {
 					res = L2CAP_CR_PEND;
 					stat = L2CAP_CS_AUTHOR_PEND;
 					chan->ops->defer(chan);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 61c10bc..a6ecf58 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -659,10 +659,13 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname,
 			break;
 		}
 
-		if (opt)
+		if (opt) {
 			set_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
-		else
+			set_bit(CONN_DEFER_SETUP, &chan->conn_state);
+		} else {
 			clear_bit(BT_SK_DEFER_SETUP, &bt_sk(sk)->flags);
+			clear_bit(CONN_DEFER_SETUP, &chan->conn_state);
+		}
 		break;
 
 	case BT_FLUSHABLE:
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 06/16] Bluetooth: use l2cap_chan_ready() instead of duplicate code
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

l2cap_chan_ready() does exactly what we want here avoiding duplicate code.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 net/bluetooth/l2cap_core.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index a035f7a..d3af9ddd 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1399,12 +1399,7 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 				l2cap_chan_ready(chan);
 
 		} else if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
-			struct sock *sk = chan->sk;
-			__clear_chan_timer(chan);
-			lock_sock(sk);
-			__l2cap_state_change(chan, BT_CONNECTED);
-			sk->sk_state_change(sk);
-			release_sock(sk);
+			l2cap_chan_ready(chan);
 
 		} else if (chan->state == BT_CONNECT) {
 			l2cap_do_start(chan);
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 05/16] Bluetooth: Add missing braces to an "else if"
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Trivial change in the coding style.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 net/bluetooth/l2cap_core.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 91e12b6..a035f7a 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1406,8 +1406,9 @@ static void l2cap_conn_ready(struct l2cap_conn *conn)
 			sk->sk_state_change(sk);
 			release_sock(sk);
 
-		} else if (chan->state == BT_CONNECT)
+		} else if (chan->state == BT_CONNECT) {
 			l2cap_do_start(chan);
+		}
 
 		l2cap_chan_unlock(chan);
 	}
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 04/16] Bluetooth: add l2cap_state_change_and_error()
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Add helper to set both state and error at the same time.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 net/bluetooth/l2cap_core.c | 18 ++++++++++--------
 1 file changed, 10 insertions(+), 8 deletions(-)

diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index e0aabe8..91e12b6 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -228,9 +228,15 @@ static void l2cap_state_change(struct l2cap_chan *chan, int state)
 	release_sock(sk);
 }
 
-static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
+static void l2cap_state_change_and_error(struct l2cap_chan *chan, int state,
+					 int err)
 {
-	chan->ops->state_change(chan, chan->state, 0);
+	struct sock *sk = chan->sk;
+
+	lock_sock(sk);
+	chan->state = state;
+	chan->ops->state_change(chan, state, err);
+	release_sock(sk);
 }
 
 static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
@@ -238,7 +244,7 @@ static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
 	struct sock *sk = chan->sk;
 
 	lock_sock(sk);
-	__l2cap_chan_set_err(chan, err);
+	chan->ops->state_change(chan, chan->state, 0);
 	release_sock(sk);
 }
 
@@ -1180,7 +1186,6 @@ static inline int l2cap_mode_supported(__u8 mode, __u32 feat_mask)
 
 static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
 {
-	struct sock *sk = chan->sk;
 	struct l2cap_conn *conn = chan->conn;
 	struct l2cap_disconn_req req;
 
@@ -1203,10 +1208,7 @@ static void l2cap_send_disconn_req(struct l2cap_chan *chan, int err)
 	l2cap_send_cmd(conn, l2cap_get_ident(conn), L2CAP_DISCONN_REQ,
 		       sizeof(req), &req);
 
-	lock_sock(sk);
-	__l2cap_state_change(chan, BT_DISCONN);
-	__l2cap_chan_set_err(chan, err);
-	release_sock(sk);
+	l2cap_state_change_and_error(chan, BT_DISCONN, err);
 }
 
 /* ---- L2CAP connections ---- */
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 03/16] Bluetooth: extend state_change() call to report errors too
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Now l2cap_core doesn't need to touch sk_err element anymore, it just tell
l2cap_sock via this call which error it wants to set.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 include/net/bluetooth/l2cap.h | 2 +-
 net/bluetooth/a2mp.c          | 2 +-
 net/bluetooth/l2cap_core.c    | 6 ++----
 net/bluetooth/l2cap_sock.c    | 5 ++++-
 4 files changed, 8 insertions(+), 7 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 0aee196..c361c47 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -551,7 +551,7 @@ struct l2cap_ops {
 	void			(*teardown) (struct l2cap_chan *chan, int err);
 	void			(*close) (struct l2cap_chan *chan);
 	void			(*state_change) (struct l2cap_chan *chan,
-						 int state);
+						 int state, int err);
 	void			(*ready) (struct l2cap_chan *chan);
 	void			(*defer) (struct l2cap_chan *chan);
 	struct sk_buff		*(*alloc_skb) (struct l2cap_chan *chan,
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
index 2f67d5e..2b6faae 100644
--- a/net/bluetooth/a2mp.c
+++ b/net/bluetooth/a2mp.c
@@ -663,7 +663,7 @@ static void a2mp_chan_close_cb(struct l2cap_chan *chan)
 	l2cap_chan_put(chan);
 }
 
-static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state)
+static void a2mp_chan_state_change_cb(struct l2cap_chan *chan, int state, int err)
 {
 	struct amp_mgr *mgr = chan->data;
 
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 1fbaf63..e0aabe8 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -216,7 +216,7 @@ static void __l2cap_state_change(struct l2cap_chan *chan, int state)
 	       state_to_string(state));
 
 	chan->state = state;
-	chan->ops->state_change(chan, state);
+	chan->ops->state_change(chan, state, 0);
 }
 
 static void l2cap_state_change(struct l2cap_chan *chan, int state)
@@ -230,9 +230,7 @@ static void l2cap_state_change(struct l2cap_chan *chan, int state)
 
 static inline void __l2cap_chan_set_err(struct l2cap_chan *chan, int err)
 {
-	struct sock *sk = chan->sk;
-
-	sk->sk_err = err;
+	chan->ops->state_change(chan, chan->state, 0);
 }
 
 static inline void l2cap_chan_set_err(struct l2cap_chan *chan, int err)
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 221aef9..61c10bc 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1044,11 +1044,14 @@ static void l2cap_sock_teardown_cb(struct l2cap_chan *chan, int err)
 	release_sock(sk);
 }
 
-static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state)
+static void l2cap_sock_state_change_cb(struct l2cap_chan *chan, int state, int err)
 {
 	struct sock *sk = chan->data;
 
 	sk->sk_state = state;
+
+	if (err)
+		sk->sk_err = err;
 }
 
 static struct sk_buff *l2cap_sock_alloc_skb_cb(struct l2cap_chan *chan,
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 02/16] Bluetooth: Remove sk_sndtimeo from l2cap_core.c
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

We now have a new struct member in l2cap_chan to store this value for
access inside l2cap_core.c

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 include/net/bluetooth/l2cap.h | 1 +
 net/bluetooth/l2cap_core.c    | 7 +++----
 net/bluetooth/l2cap_sock.c    | 1 +
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 445b71e..0aee196 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -480,6 +480,7 @@ struct l2cap_chan {
 	__u8		tx_state;
 	__u8		rx_state;
 
+	unsigned long	sndtimeo;
 	unsigned long	conf_state;
 	unsigned long	conn_state;
 	unsigned long	flags;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 4a06959..1fbaf63 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -630,7 +630,7 @@ void l2cap_chan_close(struct l2cap_chan *chan, int reason)
 	case BT_CONFIG:
 		if (chan->chan_type == L2CAP_CHAN_CONN_ORIENTED &&
 		    conn->hcon->type == ACL_LINK) {
-			__set_chan_timer(chan, sk->sk_sndtimeo);
+			__set_chan_timer(chan, chan->sndtimeo);
 			l2cap_send_disconn_req(chan, reason);
 		} else
 			l2cap_chan_del(chan, reason);
@@ -1607,7 +1607,6 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
 int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 		       bdaddr_t *dst, u8 dst_type)
 {
-	struct sock *sk = chan->sk;
 	bdaddr_t *src = &chan->src;
 	struct l2cap_conn *conn;
 	struct hci_conn *hcon;
@@ -1721,7 +1720,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 	l2cap_chan_lock(chan);
 
 	l2cap_state_change(chan, BT_CONNECT);
-	__set_chan_timer(chan, sk->sk_sndtimeo);
+	__set_chan_timer(chan, chan->sndtimeo);
 
 	if (hcon->state == BT_CONNECTED) {
 		if (chan->chan_type != L2CAP_CHAN_CONN_ORIENTED) {
@@ -3646,7 +3645,7 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
 
 	dcid = chan->scid;
 
-	__set_chan_timer(chan, sk->sk_sndtimeo);
+	__set_chan_timer(chan, chan->sndtimeo);
 
 	chan->ident = cmd->ident;
 
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 0977966..221aef9 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -1178,6 +1178,7 @@ static void l2cap_sock_init(struct sock *sk, struct sock *parent)
 
 	/* Default config options */
 	chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
+	chan->sndtimeo = sk->sk_sndtimeo;
 
 	chan->data = sk;
 	chan->ops = &l2cap_chan_ops;
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 01/16] Bluetooth: Add src and dst info to struct l2cap_chan
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan
In-Reply-To: <1355285624-25811-1-git-send-email-gustavo@padovan.org>

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

Adding these two info to l2cap_chan makes the l2cap_core.c a little more
independent of the struct sock.

Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 include/net/bluetooth/l2cap.h |  3 +++
 net/bluetooth/l2cap_core.c    | 46 ++++++++++++++++++-------------------------
 net/bluetooth/l2cap_sock.c    |  6 +++---
 3 files changed, 25 insertions(+), 30 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 7588ef4..445b71e 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -435,6 +435,9 @@ struct l2cap_seq_list {
 struct l2cap_chan {
 	struct sock *sk;
 
+	bdaddr_t	src;
+	bdaddr_t	dst;
+
 	struct l2cap_conn	*conn;
 	struct hci_conn		*hs_hcon;
 	struct hci_chan		*hs_hchan;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 2c78208..4a06959 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -148,7 +148,7 @@ static struct l2cap_chan *__l2cap_global_chan_by_addr(__le16 psm, bdaddr_t *src)
 	struct l2cap_chan *c;
 
 	list_for_each_entry(c, &chan_list, global_l) {
-		if (c->sport == psm && !bacmp(&bt_sk(c->sk)->src, src))
+		if (c->sport == psm && !bacmp(&c->src, src))
 			return c;
 	}
 	return NULL;
@@ -1305,7 +1305,6 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
 	read_lock(&chan_list_lock);
 
 	list_for_each_entry(c, &chan_list, global_l) {
-		struct sock *sk = c->sk;
 
 		if (state && c->state != state)
 			continue;
@@ -1315,16 +1314,16 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
 			int src_any, dst_any;
 
 			/* Exact match. */
-			src_match = !bacmp(&bt_sk(sk)->src, src);
-			dst_match = !bacmp(&bt_sk(sk)->dst, dst);
+			src_match = !bacmp(&c->src, src);
+			dst_match = !bacmp(&c->dst, dst);
 			if (src_match && dst_match) {
 				read_unlock(&chan_list_lock);
 				return c;
 			}
 
 			/* Closest match */
-			src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
-			dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
+			src_any = !bacmp(&c->src, BDADDR_ANY);
+			dst_any = !bacmp(&c->dst, BDADDR_ANY);
 			if ((src_match && dst_any) || (src_any && dst_match) ||
 			    (src_any && dst_any))
 				c1 = c;
@@ -1338,7 +1337,7 @@ static struct l2cap_chan *l2cap_global_chan_by_scid(int state, u16 cid,
 
 static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 {
-	struct sock *parent, *sk;
+	struct sock *parent;
 	struct l2cap_chan *chan, *pchan;
 
 	BT_DBG("");
@@ -1357,13 +1356,11 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn)
 	if (!chan)
 		goto clean;
 
-	sk = chan->sk;
-
 	hci_conn_hold(conn->hcon);
 	conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT;
 
-	bacpy(&bt_sk(sk)->src, conn->src);
-	bacpy(&bt_sk(sk)->dst, conn->dst);
+	bacpy(&chan->src, conn->src);
+	bacpy(&chan->dst, conn->dst);
 
 	l2cap_chan_add(conn, chan);
 
@@ -1577,7 +1574,6 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
 	read_lock(&chan_list_lock);
 
 	list_for_each_entry(c, &chan_list, global_l) {
-		struct sock *sk = c->sk;
 
 		if (state && c->state != state)
 			continue;
@@ -1587,16 +1583,16 @@ static struct l2cap_chan *l2cap_global_chan_by_psm(int state, __le16 psm,
 			int src_any, dst_any;
 
 			/* Exact match. */
-			src_match = !bacmp(&bt_sk(sk)->src, src);
-			dst_match = !bacmp(&bt_sk(sk)->dst, dst);
+			src_match = !bacmp(&c->src, src);
+			dst_match = !bacmp(&c->dst, dst);
 			if (src_match && dst_match) {
 				read_unlock(&chan_list_lock);
 				return c;
 			}
 
 			/* Closest match */
-			src_any = !bacmp(&bt_sk(sk)->src, BDADDR_ANY);
-			dst_any = !bacmp(&bt_sk(sk)->dst, BDADDR_ANY);
+			src_any = !bacmp(&c->src, BDADDR_ANY);
+			dst_any = !bacmp(&c->dst, BDADDR_ANY);
 			if ((src_match && dst_any) || (src_any && dst_match) ||
 			    (src_any && dst_any))
 				c1 = c;
@@ -1612,7 +1608,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 		       bdaddr_t *dst, u8 dst_type)
 {
 	struct sock *sk = chan->sk;
-	bdaddr_t *src = &bt_sk(sk)->src;
+	bdaddr_t *src = &chan->src;
 	struct l2cap_conn *conn;
 	struct hci_conn *hcon;
 	struct hci_dev *hdev;
@@ -1679,9 +1675,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 	}
 
 	/* Set destination address and psm */
-	lock_sock(sk);
-	bacpy(&bt_sk(sk)->dst, dst);
-	release_sock(sk);
+	bacpy(&chan->dst, dst);
 
 	chan->psm = psm;
 	chan->dcid = cid;
@@ -3642,8 +3636,8 @@ static struct l2cap_chan *l2cap_connect(struct l2cap_conn *conn,
 
 	hci_conn_hold(conn->hcon);
 
-	bacpy(&bt_sk(sk)->src, conn->src);
-	bacpy(&bt_sk(sk)->dst, conn->dst);
+	bacpy(&chan->src, conn->src);
+	bacpy(&chan->dst, conn->dst);
 	chan->psm  = psm;
 	chan->dcid = scid;
 	chan->local_amp_id = amp_id;
@@ -6279,17 +6273,16 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
 	/* Find listening sockets and check their link_mode */
 	read_lock(&chan_list_lock);
 	list_for_each_entry(c, &chan_list, global_l) {
-		struct sock *sk = c->sk;
 
 		if (c->state != BT_LISTEN)
 			continue;
 
-		if (!bacmp(&bt_sk(sk)->src, &hdev->bdaddr)) {
+		if (!bacmp(&c->src, &hdev->bdaddr)) {
 			lm1 |= HCI_LM_ACCEPT;
 			if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
 				lm1 |= HCI_LM_MASTER;
 			exact++;
-		} else if (!bacmp(&bt_sk(sk)->src, BDADDR_ANY)) {
+		} else if (!bacmp(&c->src, BDADDR_ANY)) {
 			lm2 |= HCI_LM_ACCEPT;
 			if (test_bit(FLAG_ROLE_SWITCH, &c->flags))
 				lm2 |= HCI_LM_MASTER;
@@ -6573,10 +6566,9 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p)
 	read_lock(&chan_list_lock);
 
 	list_for_each_entry(c, &chan_list, global_l) {
-		struct sock *sk = c->sk;
 
 		seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
-			   &bt_sk(sk)->src, &bt_sk(sk)->dst,
+			   &c->src, &c->dst,
 			   c->state, __le16_to_cpu(c->psm),
 			   c->scid, c->dcid, c->imtu, c->omtu,
 			   c->sec_level, c->mode);
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c
index 1bcfb84..0977966 100644
--- a/net/bluetooth/l2cap_sock.c
+++ b/net/bluetooth/l2cap_sock.c
@@ -97,7 +97,7 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen)
 	    __le16_to_cpu(la.l2_psm) == L2CAP_PSM_RFCOMM)
 		chan->sec_level = BT_SECURITY_SDP;
 
-	bacpy(&bt_sk(sk)->src, &la.l2_bdaddr);
+	bacpy(&chan->src, &la.l2_bdaddr);
 
 	chan->state = BT_BOUND;
 	sk->sk_state = BT_BOUND;
@@ -259,11 +259,11 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr,
 
 	if (peer) {
 		la->l2_psm = chan->psm;
-		bacpy(&la->l2_bdaddr, &bt_sk(sk)->dst);
+		bacpy(&la->l2_bdaddr, &chan->dst);
 		la->l2_cid = cpu_to_le16(chan->dcid);
 	} else {
 		la->l2_psm = chan->sport;
-		bacpy(&la->l2_bdaddr, &bt_sk(sk)->src);
+		bacpy(&la->l2_bdaddr, &chan->src);
 		la->l2_cid = cpu_to_le16(chan->scid);
 	}
 
-- 
1.7.11.7


^ permalink raw reply related

* [RFC 00/16] Completely remove socket dependency from l2cap_core.c
From: Gustavo Padovan @ 2012-12-12  4:13 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Gustavo Padovan

From: Gustavo Padovan <gustavo.padovan@collabora.co.uk>

This is the last series of patches to completely remove the l2cap socket usage
in the l2cap_core.c file. We now have a C API to access L2CAP and as a next
step we should convert RFCOMM to use this API.

Gustavo Padovan (16):
  Bluetooth: Add src and dst info to struct l2cap_chan
  Bluetooth: Remove sk_sndtimeo from l2cap_core.c
  Bluetooth: extend state_change() call to report errors too
  Bluetooth: add l2cap_state_change_and_error()
  Bluetooth: Add missing braces to an "else if"
  Bluetooth: use l2cap_chan_ready() instead of duplicate code
  Bluetooth: duplicate DEFER_SETUP flag on l2cap_chan
  Bluetooth: Improving locking in l2cap_conn_start()
  Bluetooth: lock socket in defer_cb call
  Bluetooth: Remove socket lock from state_change() in l2cap_core
  Bluetooth: remove parent socket usage from l2cap_core.c
  Bluetooth: Use abstract chan->data in comparison
  Bluetooth: Move l2cap_wait_ack() to l2cap_sock.c
  Bluetooth: Create l2cap->ops->resume()
  Bluetooth: Create l2cap->ops->set_shutdown()
  Bluetooth: Remove sk member from struct l2cap_chan

 include/net/bluetooth/l2cap.h |  20 ++++-
 net/bluetooth/a2mp.c          |   4 +-
 net/bluetooth/l2cap_core.c    | 200 ++++++++++++------------------------------
 net/bluetooth/l2cap_sock.c    |  95 +++++++++++++++++---
 4 files changed, 159 insertions(+), 160 deletions(-)

-- 
1.7.11.7


^ permalink raw reply

* [BLE] org.bluez.Device1.Connect() returns org.bluez.Error.NotAvailable
From: Ting Chou @ 2012-12-12  3:57 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org

Hello,

The Problem
-----------

I am trying to connect to a BLE device (thermometer) by the D-Bus API with
following steps:

  1. Call org.bluez.Device1.Connect(), got org.bluez.Error.NotAvailable. But
     from the log of hcidump, the device is connected.
  2. Invoke org.bluez.Device1.Disconnect(), hcidump shows it is disconnected.
  3. Connect again, org.bluez.Device1.Connect() still throws
     org.bluez.Error.NotAvailable, but this time, there's nothing from hcidump,
     i.e., the device is not connected.

I'm not sure is this expected or it is a bug. If this is a bug, and you don't
have time to fix it, I'd love to help, but I may need a mentor.

Reproduce Steps
---------------

1. ting@user-OptiPlex-755:~/w/bluez$ sudo test/test-discovery -i hci0
   [ 00:07:80:4C:5F:17 ]
       Name = DKBLE112 thermometer
       Paired = 0
       Adapter = /org/bluez/hci0
       LegacyPairing = 0
       Alias = DKBLE112 thermometer
       Connected = 0
       Address = 00:07:80:4C:5F:17
       RSSI = -66
       Trusted = 0
       Blocked = 0
   ting@user-OptiPlex-755:~/w/bluez$ sudo test/test-device connect 00:07:80:4C:5F:17
   Traceback (most recent call last):
     File "test/test-device", line 104, in <module>
       device.ConnectProfile(args[2])
     File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 70, in __call__
       return self._proxy_method(*args, **keywords)
     File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 145, in __call__
       **keywords)
     File "/usr/lib/python2.7/dist-packages/dbus/connection.py", line 651, in call_blocking
       message, timeout)
   dbus.exceptions.DBusException: org.bluez.Error.NotAvailable: Operation currently not available

2. ting@user-OptiPlex-755:~/w/bluez$ sudo test/test-device disconnect 00:1C:4D:00:09:02

3. ting@user-OptiPlex-755:~/w/bluez$ sudo test/test-device connect 00:07:80:4C:5F:17
   Traceback (most recent call last):
     File "test/test-device", line 104, in <module>
       device.ConnectProfile(args[2])
     File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 70, in __call__
       return self._proxy_method(*args, **keywords)
     File "/usr/lib/python2.7/dist-packages/dbus/proxies.py", line 145, in __call__
       **keywords)
     File "/usr/lib/python2.7/dist-packages/dbus/connection.py", line 651, in call_blocking
       message, timeout)
   dbus.exceptions.DBusException: org.bluez.Error.NotAvailable: Operation currently not available

I Found
-------

- I checked /var/log/syslog and src/device.c, and found connect_profiles() is
  called twice at the first time calling org.bluez.Device.Connect():

  - 1st time
    dev->svc_resolved==FALSE, device_resolve_svc() is invoked.

  - 2nd time
    dev->svc_resolved==TRUE
    In the for loop of iterating device profiles, there're two profiles:

      a) p->auto_connect==FALSE, p->name==deviceinfo, p->local_uuid==NULL
      b) p->auto_connect==FALSE, p->name==Health Thermometer GATT driver, p->local_uuid==NULL

    Since none of them have auto_connect TRUE, dev->pending==NULL, and
    btd_error_not_available() is called.

- I tried org.bluez.Device1.ConnectProfile() as well, but since all the profiles
  have local_uuid NULL, find_connectable_profile() return NULL and
  btd_error_invalid_args() is called.

Regards,
Ting

^ permalink raw reply

* Re: [PATCH ] Bluetooth: Remove unnecessary include l2cap.h.
From: Gustavo Padovan @ 2012-12-11 22:26 UTC (permalink / raw)
  To: Rami Rosen; +Cc: linux-bluetooth, marcel, johan.hedberg
In-Reply-To: <1354943305-7069-1-git-send-email-ramirose@gmail.com>

Hi Rami,

* Rami Rosen <ramirose@gmail.com> [2012-12-08 07:08:25 +0200]:

> This patch removes unnecessary include of <net/bluetooth/l2cap.h>
> in bluetooth/bnep/core.c.
> 
> Signed-off-by: Rami Rosen <ramirose@gmail.com>
> ---
>  net/bluetooth/bnep/core.c | 1 -
>  1 file changed, 1 deletion(-)

Patch has been applied to bluetooth-next. Thanks.

	Gustavo

^ permalink raw reply

* Re: [PATCH] Bluetooth: Fix sending HCI commands after reset
From: Gustavo Padovan @ 2012-12-11 22:24 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, stable
In-Reply-To: <1355212279-2069-1-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

* Szymon Janc <szymon.janc@tieto.com> [2012-12-11 08:51:19 +0100]:

> After sending reset command wait for its command complete event before
> sending next command. Some chips sends CC event for command received
> before reset if reset was send before chip replied with CC.
> 
> This is also required by specification that host shall not send
> additional HCI commands before receiving CC for reset.
> 
> < HCI Command: Reset (0x03|0x0003) plen 0                              [hci0] 18.404612
> > HCI Event: Command Complete (0x0e) plen 4                            [hci0] 18.405850
>       Write Extended Inquiry Response (0x03|0x0052) ncmd 1
>         Status: Success (0x00)
> < HCI Command: Read Local Supported Features (0x04|0x0003) plen 0      [hci0] 18.406079
> > HCI Event: Command Complete (0x0e) plen 4                            [hci0] 18.407864
>       Reset (0x03|0x0003) ncmd 1
>         Status: Success (0x00)
> < HCI Command: Read Local Supported Features (0x04|0x0003) plen 0      [hci0] 18.408062
> > HCI Event: Command Complete (0x0e) plen 12                           [hci0] 18.408835
> 
> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> Cc: stable@vger.kernel.org
> Acked-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
>  net/bluetooth/hci_event.c |    2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)

Patch has been applied to bluetooth.git. Thanks.

	Gustavo

^ permalink raw reply


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