Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v4 0/5] L2CAP updates for FCS, valid PSMs, and stream recv
From: Mat Martineau @ 2010-08-10 19:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, gustavo, rshaffer, linux-arm-msm

The previous version of this patch set was "[PATCH v3 0/9] Bluetooth:
L2CAP updates for PSM validation and ERTM" - four patches were already
merged, and this group of patches incorporates additional feedback
from the v3 iteration.

^ permalink raw reply

* Re: patch for firmware download to Qualcomm Bluetooth chip
From: Ron Shaffer @ 2010-08-10 18:51 UTC (permalink / raw)
  To: linux-bluetooth, Marcel Holtmann, johan.hedberg

Marcel:

Here's the a ping regarding the patch submitted by Matt back in March? I
believe. For you convenience I've included the patch again. Please take
a look, and provide your general comments. I'm sure there are changes
that need to be made.

Fyi. sorry about the column wrap in the patch. Don't feel like fixing it
for just a quick review.

>From 76d0bdd82a0a4e5b3b9544bb864c31888f20cea1 Mon Sep 17 00:00:00 2001
From: Wilson, Matt <mtwilson@codeaurora.org>
Date: Thu, 11 Feb 2010 11:53:29 -0600
Subject: [PATCH] Firmware download for Qualcomm Bluetooth devices

---
 Makefile.tools             |    3 +-
 tools/hciattach.c          |    9 ++
 tools/hciattach.h          |    4 +
 tools/hciattach_qualcomm.c |  279
++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 294 insertions(+), 1 deletions(-)
 create mode 100644 tools/hciattach_qualcomm.c

diff --git a/Makefile.tools b/Makefile.tools
index 2735d68..7b92c8f 100644
--- a/Makefile.tools
+++ b/Makefile.tools
@@ -23,7 +23,8 @@ tools_l2ping_LDADD = lib/libbluetooth.la
 tools_hciattach_SOURCES = tools/hciattach.c tools/hciattach.h \
 						tools/hciattach_st.c \
 						tools/hciattach_ti.c \
-						tools/hciattach_tialt.c
+						tools/hciattach_tialt.c \
+						tools/hciattach_qualcomm.c
 tools_hciattach_LDADD = lib/libbluetooth.la

 tools_hciconfig_SOURCES = tools/hciconfig.c tools/csr.h tools/csr.c \
diff --git a/tools/hciattach.c b/tools/hciattach.c
index 364c5ff..d6aafbe 100644
--- a/tools/hciattach.c
+++ b/tools/hciattach.c
@@ -5,6 +5,7 @@
  *  Copyright (C) 2000-2001  Qualcomm Incorporated
  *  Copyright (C) 2002-2003  Maxim Krasnyansky <maxk@qualcomm.com>
  *  Copyright (C) 2002-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (C) 2010, Code Aurora Forum. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -299,6 +300,11 @@ static int texasalt(int fd, struct uart_t *u, struct
termios *ti)
 	return texasalt_init(fd, u->speed, ti);
 }

+static int qualcomm(int fd, struct uart_t *u, struct termios *ti)
+{
+	return qualcomm_init(fd, u->speed, ti, u->bdaddr);
+}
+
 static int read_check(int fd, void *buf, int count)
 {
 	int res;
@@ -1071,6 +1077,9 @@ struct uart_t uart[] = {
 	/* Broadcom BCM2035 */
 	{ "bcm2035",    0x0A5C, 0x2035, HCI_UART_H4,   115200, 460800, FLOW_CTL,
NULL, bcm2035  },

+	/* QUALCOMM BTS */
+	{ "qualcomm",   0x0000, 0x0000, HCI_UART_H4,   115200, 115200, FLOW_CTL,
NULL, qualcomm },
+
 	{ NULL, 0 }
 };

diff --git a/tools/hciattach.h b/tools/hciattach.h
index 867563b..5c89013 100644
--- a/tools/hciattach.h
+++ b/tools/hciattach.h
@@ -3,6 +3,7 @@
  *  BlueZ - Bluetooth protocol stack for Linux
  *
  *  Copyright (C) 2003-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
  *
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -45,3 +46,6 @@ int texas_post(int fd, struct termios *ti);
 int texasalt_init(int fd, int speed, struct termios *ti);
 int stlc2500_init(int fd, bdaddr_t *bdaddr);
 int bgb2xx_init(int dd, bdaddr_t *bdaddr);
+int qualcomm_init(int fd, int speed, struct termios *ti, const char
*bdaddr);
+
+
diff --git a/tools/hciattach_qualcomm.c b/tools/hciattach_qualcomm.c
new file mode 100644
index 0000000..31ca3c8
--- /dev/null
+++ b/tools/hciattach_qualcomm.c
@@ -0,0 +1,279 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2005-2010  Marcel Holtmann <marcel@holtmann.org>
+ *  Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+#include <syslog.h>
+#include <termios.h>
+#include <time.h>
+#include <sys/time.h>
+#include <sys/poll.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <sys/uio.h>
+
+#include <bluetooth/bluetooth.h>
+#include <bluetooth/hci.h>
+#include <bluetooth/hci_lib.h>
+
+#include "hciattach.h"
+
+#define FAILIF(x, args...) do {   \
+	if (x) {					  \
+		fprintf(stderr, ##args);  \
+		return -1;				  \
+	}							  \
+} while(0)
+
+typedef struct {
+	uint8_t uart_prefix;
+	hci_event_hdr hci_hdr;
+	evt_cmd_complete cmd_complete;
+	uint8_t status;
+	uint8_t data[16];
+} __attribute__((packed)) command_complete_t;
+
+
+static int read_command_complete(int fd, unsigned short opcode, unsigned
char len) {
+	command_complete_t resp;
+	unsigned char vsevent[512];
+	int n;
+
+	/* Read reply. */
+	n = read_hci_event(fd, vsevent, sizeof(vsevent));
+	FAILIF(n < 0, "Failed to read response");
+
+	FAILIF(vsevent[1] != 0xFF, "Failed to read response");
+
+	n = read_hci_event(fd, (unsigned char *)&resp, sizeof(resp));
+	FAILIF(n < 0, "Failed to read response");
+
+	FAILIF(resp.hci_hdr.evt != EVT_CMD_COMPLETE, /* event must be event-
complete */
+		   "Error in response: not a cmd-complete event, "
+		   "but 0x%02x!\n", resp.hci_hdr.evt);
+
+	FAILIF(resp.hci_hdr.plen < 4, /* plen >= 4 for EVT_CMD_COMPLETE */
+		   "Error in response: plen is not >= 4, but 0x%02x!\n",
+		   resp.hci_hdr.plen);
+
+	/* cmd-complete event: opcode */
+	FAILIF(resp.cmd_complete.opcode != 0,
+		   "Error in response: opcode is 0x%04x, not 0!",
+		   resp.cmd_complete.opcode);
+
+	return resp.status == 0 ? 0 : -1;
+}
+
+static int qualcomm_load_firmware(int fd, const char *firmware, const
char *
bdaddr_s) {
+
+	int fw = open(firmware, O_RDONLY);
+
+	fprintf(stdout, "Opening firmware file: %s\n", firmware);
+
+	FAILIF(fw < 0,
+		   "Could not open firmware file %s: %s (%d).\n",
+		   firmware, strerror(errno), errno);
+
+	fprintf(stdout, "Uploading firmware...\n");
+	do {
+		/* Read each command and wait for a response. */
+		unsigned char data[1024];
+		unsigned char cmdp[1 + sizeof(hci_command_hdr)];
+		hci_command_hdr *cmd = (hci_command_hdr *)(cmdp + 1);
+		int nr;
+		nr = read(fw, cmdp, sizeof(cmdp));
+		if (!nr)
+			break;
+		FAILIF(nr != sizeof(cmdp), "Could not read H4 + HCI header!\n");
+		FAILIF(*cmdp != HCI_COMMAND_PKT, "Command is not an H4 command
packet!\n");
+
+		FAILIF(read(fw, data, cmd->plen) != cmd->plen,
+			   "Could not read %d bytes of data for command with opcode %04x!\n",
+			   cmd->plen,
+			   cmd->opcode);
+
+		if ((data[0] == 1) && (data[1] == 2) && (data[2] == 6)) {
+			bdaddr_t bdaddr;
+			if (bdaddr_s != NULL) {
+				(void) str2ba(bdaddr_s, &bdaddr);
+				memcpy(&data[3], &bdaddr, sizeof(bdaddr_t));
+			}
+		}
+
+		{
+			int nw;
+			struct iovec iov_cmd[2];
+			iov_cmd[0].iov_base = cmdp;
+			iov_cmd[0].iov_len	= sizeof(cmdp);
+			iov_cmd[1].iov_base = data;
+			iov_cmd[1].iov_len	= cmd->plen;
+			nw = writev(fd, iov_cmd, 2);
+			FAILIF(nw != (int) sizeof(cmdp) + cmd->plen,
+				   "Could not send entire command (sent only %d bytes)!\n",
+				   nw);
+		}
+
+		/* Wait for response */
+		if (read_command_complete(fd,
+					  cmd->opcode,
+					  cmd->plen) < 0) {
+			return -1;
+		}
+
+	} while(1);
+	fprintf(stdout, "Firmware upload successful.\n");
+
+	close(fw);
+	return 0;
+}
+
+int qualcomm_init(int fd, int speed, struct termios *ti, const char
*bdaddr)
+{
+	struct timespec tm = {0, 50000};
+	char cmd[5];
+	unsigned char resp[100];		/* Response */
+	char fw[100];
+	int n;
+
+	memset(resp,'\0', 100);
+
+	/* Get Manufacturer and LMP version */
+	cmd[0] = HCI_COMMAND_PKT;
+	cmd[1] = 0x01;
+	cmd[2] = 0x10;
+	cmd[3] = 0x00;
+
+	do {
+		n = write(fd, cmd, 4);
+		if (n < 0) {
+			perror("Failed to write init command (READ_LOCAL_VERSION_INFORMATION)");
+			return -1;
+		}
+		if (n < 4) {
+			fprintf(stderr, "Wanted to write 4 bytes, could only write %d.
Stop\n", n);
+			return -1;
+		}
+
+		/* Read reply. */
+		if (read_hci_event(fd, resp, 100) < 0) {
+			perror("Failed to read init response (READ_LOCAL_VERSION_INFORMATION)");
+			return -1;
+		}
+
+		/* Wait for command complete event for our Opcode */
+	} while (resp[4] != cmd[1] && resp[5] != cmd[2]);
+
+	/* Verify manufacturer */
+	if ((resp[11] & 0xFF) != 0x1d)
+		fprintf(stderr,"WARNING : module's manufacturer is not Qualcomm\n");
+
+	/* Print LMP version */
+	fprintf(stderr, "Qualcomm module LMP version : 0x%02x\n", resp[10] &
0xFF);
+
+	/* Print LMP subversion */
+	{
+		unsigned short lmp_subv = resp[13] | (resp[14] << 8);
+
+		fprintf(stderr, "Qualcomm module LMP sub-version : 0x%04x\n", lmp_subv);
+
+	}
+
+	/* Get SoC type */
+	cmd[0] = HCI_COMMAND_PKT;
+	cmd[1] = 0x00;
+	cmd[2] = 0xFC;
+	cmd[3] = 0x01;
+	cmd[4] = 0x06;
+
+	do {
+		n = write(fd, cmd, 5);
+		if (n < 0) {
+			perror("Failed to write init command");
+			return -1;
+		}
+		if (n < 5) {
+			fprintf(stderr, "Wanted to write 5 bytes, could only write %d.
Stop\n", n);
+			return -1;
+		}
+
+		/* Read reply. */
+		if ((n = read_hci_event(fd, resp, 100)) < 0) {
+			perror("Failed to read init response");
+			return -1;
+		}
+
+	} while (resp[3] != 0 && resp[4] != 2);
+
+	snprintf(fw, sizeof(fw),
+		"/etc/firmware/%c%c%c%c%c%c_%c%c%c%c.bin",
+		resp[18], resp[19], resp[20], resp[21],
+		resp[22], resp[23],
+		resp[32], resp[33], resp[34], resp[35]);
+
+	/* Wait for command complete event for our Opcode */
+	if (read_hci_event(fd, resp, 100) < 0) {
+		perror("Failed to read init response");
+		return -1;
+	}
+
+	qualcomm_load_firmware(fd, fw, bdaddr);
+
+	/* Reset */
+	cmd[0] = HCI_COMMAND_PKT;
+	cmd[1] = 0x03;
+	cmd[2] = 0x0C;
+	cmd[3] = 0x00;
+
+	do {
+		n = write(fd, cmd, 4);
+		if (n < 0) {
+			perror("Failed to write reset command");
+			return -1;
+		}
+		if (n < 4) {
+			fprintf(stderr, "Wanted to write 4 bytes, could only write %d.
Stop\n", n);
+			return -1;
+		}
+
+		/* Read reply. */
+		if ((n = read_hci_event(fd, resp, 100)) < 0) {
+			perror("Failed to read reset response");
+			return -1;
+		}
+
+	} while (resp[4] != cmd[1] && resp[5] != cmd[2]);
+
+	nanosleep(&tm, NULL);
+	return 0;
+}
-- 
1.6.3.3
-- 
Ron Shaffer
Employee of the Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 2/2] Use HCI device type to gate BR/EDR-specific HCI commands
From: David Scherba @ 2010-08-10 15:45 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, marcel, rshaffer, David Scherba
In-Reply-To: <4C6173CA.8060308@codeaurora.org>

Use the hci_dev_info structure member 'type' to classify whether a HCI device
is BR/EDR, or not.  If not, gate BR/EDR-specific HCI commands.
---
 lib/hci_lib.h    |    5 +++++
 plugins/hciops.c |   20 +++++++++++++-------
 src/adapter.c    |    2 +-
 src/security.c   |    4 ++--
 4 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/lib/hci_lib.h b/lib/hci_lib.h
index b63a2a4..814672d 100644
--- a/lib/hci_lib.h
+++ b/lib/hci_lib.h
@@ -169,6 +169,11 @@ static inline int hci_test_bit(int nr, void *addr)
 	return *((uint32_t *) addr + (nr >> 5)) & (1 << (nr & 31));
 }
 
+static inline int ignore_device(struct hci_dev_info *di)
+{
+	return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR;
+}
+
 /* HCI filter tools */
 static inline void hci_filter_clear(struct hci_filter *f)
 {
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 3e3e172..9c97c5a 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -85,7 +85,7 @@ static void device_devup_setup(int index)
 	if (hci_devinfo(index, &di) < 0)
 		return;
 
-	if (hci_test_bit(HCI_RAW, &di.flags))
+	if (ignore_device(&di))
 		return;
 
 	dd = hci_open_dev(index);
@@ -122,6 +122,7 @@ static void device_devup_setup(int index)
 static void init_device(int index)
 {
 	struct hci_dev_req dr;
+	struct hci_dev_info di;
 	pid_t pid;
 	int dd, err;
 
@@ -159,12 +160,17 @@ static void init_device(int index)
 					index, strerror(err), err);
 	}
 
-	/* Set link policy */
-	dr.dev_opt = main_opts.link_policy;
-	if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 &&
+	/* Set link policy for BR/EDR HCI devices */
+	if (hci_devinfo(index, &di) < 0)
+		goto fail;
+
+	if (!ignore_device(&di)) {
+		dr.dev_opt = main_opts.link_policy;
+		if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 &&
 							errno != ENETDOWN) {
-		error("Can't set link policy on hci%d: %s (%d)",
-					index, strerror(errno), errno);
+			error("Can't set link policy on hci%d: %s (%d)",
+						index, strerror(errno), errno);
+		}
 	}
 
 	/* Start HCI device */
@@ -196,7 +202,7 @@ static void device_devreg_setup(int index)
 
 	devup = hci_test_bit(HCI_UP, &di.flags);
 
-	if (!hci_test_bit(HCI_RAW, &di.flags))
+	if (!ignore_device(&di))
 		manager_register_adapter(index, devup);
 }
 
diff --git a/src/adapter.c b/src/adapter.c
index af44a59..fc1e123 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2300,7 +2300,7 @@ int adapter_start(struct btd_adapter *adapter)
 	if (hci_devinfo(adapter->dev_id, &di) < 0)
 		return -errno;
 
-	if (hci_test_bit(HCI_RAW, &di.flags)) {
+	if (ignore_device(&di)) {
 		dev->ignore = 1;
 		return -1;
 	}
diff --git a/src/security.c b/src/security.c
index ca394e1..667f1f1 100644
--- a/src/security.c
+++ b/src/security.c
@@ -999,7 +999,7 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond,
 
 	ioctl(dev, HCIGETDEVINFO, (void *) di);
 
-	if (hci_test_bit(HCI_RAW, &di->flags))
+	if (ignore_device(di))
 		return TRUE;
 
 	switch (eh->evt) {
@@ -1185,7 +1185,7 @@ void start_security_manager(int hdev)
 	io_data[hdev].channel = chan;
 	io_data[hdev].pin_length = -1;
 
-	if (hci_test_bit(HCI_RAW, &di->flags))
+	if (ignore_device(di))
 		return;
 
 	bacpy(&cp.bdaddr, BDADDR_ANY);
-- 
1.7.0.2
-- 
David Scherba
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* Re: [PATCH 2/2] Use HCI device type to gate BR/EDR-specific HCI commands
From: David Scherba @ 2010-08-10 15:44 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, marcel, rshaffer
In-Reply-To: <1281453304-30408-3-git-send-email-dscherba@codeaurora.org>

On 8/10/2010 10:15 AM, David Scherba wrote:
> -	if (!hci_test_bit(HCI_RAW,&di.flags))
> +	if (ignore_device(&di))

Johan--

This change is functionally incorrect--sorry about that.  Updating patch 
2/2.

Cheers,
David

-- 
David Scherba
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply

* [PATCH 2/2] Use HCI device type to gate BR/EDR-specific HCI commands
From: David Scherba @ 2010-08-10 15:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, marcel, rshaffer, David Scherba
In-Reply-To: <1281453304-30408-1-git-send-email-dscherba@codeaurora.org>

Use the hci_dev_info structure member 'type' to classify whether a HCI device
is BR/EDR, or not.  If not, gate BR/EDR-specific HCI commands.
---
 lib/hci_lib.h    |    5 +++++
 plugins/hciops.c |   20 +++++++++++++-------
 src/adapter.c    |    2 +-
 src/security.c   |    4 ++--
 4 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/lib/hci_lib.h b/lib/hci_lib.h
index b63a2a4..814672d 100644
--- a/lib/hci_lib.h
+++ b/lib/hci_lib.h
@@ -169,6 +169,11 @@ static inline int hci_test_bit(int nr, void *addr)
 	return *((uint32_t *) addr + (nr >> 5)) & (1 << (nr & 31));
 }
 
+static inline int ignore_device(struct hci_dev_info *di)
+{
+	return hci_test_bit(HCI_RAW, &di->flags) || di->type >> 4 != HCI_BREDR;
+}
+
 /* HCI filter tools */
 static inline void hci_filter_clear(struct hci_filter *f)
 {
diff --git a/plugins/hciops.c b/plugins/hciops.c
index 3e3e172..54c5bc0 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -85,7 +85,7 @@ static void device_devup_setup(int index)
 	if (hci_devinfo(index, &di) < 0)
 		return;
 
-	if (hci_test_bit(HCI_RAW, &di.flags))
+	if (ignore_device(&di))
 		return;
 
 	dd = hci_open_dev(index);
@@ -122,6 +122,7 @@ static void device_devup_setup(int index)
 static void init_device(int index)
 {
 	struct hci_dev_req dr;
+	struct hci_dev_info di;
 	pid_t pid;
 	int dd, err;
 
@@ -159,12 +160,17 @@ static void init_device(int index)
 					index, strerror(err), err);
 	}
 
-	/* Set link policy */
-	dr.dev_opt = main_opts.link_policy;
-	if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 &&
+	/* Set link policy for BR/EDR HCI devices */
+	if (hci_devinfo(index, &di) < 0)
+		goto fail;
+
+	if (!ignore_device(&di)) {
+		dr.dev_opt = main_opts.link_policy;
+		if (ioctl(dd, HCISETLINKPOL, (unsigned long) &dr) < 0 &&
 							errno != ENETDOWN) {
-		error("Can't set link policy on hci%d: %s (%d)",
-					index, strerror(errno), errno);
+			error("Can't set link policy on hci%d: %s (%d)",
+						index, strerror(errno), errno);
+		}
 	}
 
 	/* Start HCI device */
@@ -196,7 +202,7 @@ static void device_devreg_setup(int index)
 
 	devup = hci_test_bit(HCI_UP, &di.flags);
 
-	if (!hci_test_bit(HCI_RAW, &di.flags))
+	if (ignore_device(&di))
 		manager_register_adapter(index, devup);
 }
 
diff --git a/src/adapter.c b/src/adapter.c
index af44a59..fc1e123 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2300,7 +2300,7 @@ int adapter_start(struct btd_adapter *adapter)
 	if (hci_devinfo(adapter->dev_id, &di) < 0)
 		return -errno;
 
-	if (hci_test_bit(HCI_RAW, &di.flags)) {
+	if (ignore_device(&di)) {
 		dev->ignore = 1;
 		return -1;
 	}
diff --git a/src/security.c b/src/security.c
index ca394e1..667f1f1 100644
--- a/src/security.c
+++ b/src/security.c
@@ -999,7 +999,7 @@ static gboolean io_security_event(GIOChannel *chan, GIOCondition cond,
 
 	ioctl(dev, HCIGETDEVINFO, (void *) di);
 
-	if (hci_test_bit(HCI_RAW, &di->flags))
+	if (ignore_device(di))
 		return TRUE;
 
 	switch (eh->evt) {
@@ -1185,7 +1185,7 @@ void start_security_manager(int hdev)
 	io_data[hdev].channel = chan;
 	io_data[hdev].pin_length = -1;
 
-	if (hci_test_bit(HCI_RAW, &di->flags))
+	if (ignore_device(di))
 		return;
 
 	bacpy(&cp.bdaddr, BDADDR_ANY);
-- 
1.7.0.2
-- 
David Scherba
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH 1/2] Remove non-functional hci_devinfo calls in init_device()
From: David Scherba @ 2010-08-10 15:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, marcel, rshaffer, David Scherba
In-Reply-To: <1281453304-30408-1-git-send-email-dscherba@codeaurora.org>

---
 plugins/hciops.c |    8 --------
 1 files changed, 0 insertions(+), 8 deletions(-)

diff --git a/plugins/hciops.c b/plugins/hciops.c
index 5775cf1..3e3e172 100644
--- a/plugins/hciops.c
+++ b/plugins/hciops.c
@@ -122,7 +122,6 @@ static void device_devup_setup(int index)
 static void init_device(int index)
 {
 	struct hci_dev_req dr;
-	struct hci_dev_info di;
 	pid_t pid;
 	int dd, err;
 
@@ -175,13 +174,6 @@ static void init_device(int index)
 		goto fail;
 	}
 
-	if (hci_devinfo(index, &di) < 0)
-		goto fail;
-
-	if (hci_test_bit(HCI_RAW, &di.flags))
-		goto done;
-
-done:
 	hci_close_dev(dd);
 	exit(0);
 
-- 
1.7.0.2
-- 
David Scherba
Sent by an employee of the Qualcomm Innovation Center, Inc.
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.

^ permalink raw reply related

* [PATCH v2 0/2] Use HCI device type to determine suitability of HCI commands
From: David Scherba @ 2010-08-10 15:15 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: johan.hedberg, marcel, rshaffer

BlueZ assumes that HCI devices are either BR/EDR radios, or "RAW" (via
HCI_RAW).  At present, alternate radios are handled as RAW (reference
Marcel's 943da25d9 kernel commit).  More subtlety in BlueZ is useful as
AMP support is enhanced.

These patches remove the need to treat non-BR/EDR HCI devices as "RAW."

Cheers,
David

-- 
David Scherba
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply

* Re: Question about BlueZ licenses (LGPL and Apache)
From: Pavan Savoy @ 2010-08-10 15:14 UTC (permalink / raw)
  To: Luiz Augusto von Dentz; +Cc: Madhavi Manchala, linux-bluetooth
In-Reply-To: <AANLkTin77QjQ5KGyLmMNZeAdaC+Bs9Ny97pWEBLO39FY@mail.gmail.com>

On Tue, Aug 10, 2010 at 2:49 AM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> Hi,
>
> On Mon, Aug 9, 2010 at 10:37 PM, Pavan Savoy <pavan_savoy@sify.com> wrote:
>> As long as we are updating, can the liba2dp be abstracted out of not
>> only the sbc encoding part but also the sending over UART part (as in
>> transport ...)
>>
>> chips are getting smarter and the sbc codecs are moving to either a
>> co-processor/dsp or even inside the BT chip itself, so we might have
>> to send the PCM raw data somewhere else for the dsp to encode to sbc
>> and send it over the air ...
>>
>> currently the data (sbc/pcm) and the control (connection
>> establishment) is too tightly sort of coded in together.. isn't it ?
>>
>> for something like the above to happen our liba2dp had to be almost
>> re-written ...
>
> Im afraid liba2dp is some android specific thing, not upstream, and as
> I said before upstream is probably going to use dbus to pass the fd
> around, so this is probably not relevant here.

May be but isn't the same in pcm_bluetooth plugin too ?
If I had to support such a feature where I am only bothered about the
connection/control path and don't have to bother about data, how best
can I make use of this pcm_bluetooth ?

Specifically, I need something only to set-up the stream and the
bluetoothd being in START_STREAM sort of state, and the data is being
pumped into say another alsa-sink which is connected to dsp's pcm
input or h/w sbc encoder's pcm input.

PS:
sorry for the noise... i am just thinking aloud here,
And yes we do have a sort of working way on bluez to support such
things, but it involves hacked up code where we sort of comment out
the pieces of code...

> Luiz Augusto von Dentz
> Computer Engineer
>

^ permalink raw reply

* Re: [PATCH 1/2] Remove non-functional hci_devinfo calls in init_device()
From: David Scherba @ 2010-08-10 15:12 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: marcel, rshaffer
In-Reply-To: <20100809215149.GA25488@jh-x301>

On 8/9/2010 4:51 PM, Johan Hedberg wrote:

> Nice catch, but that's not quite enough:
>
> plugins/hciops.c: In function ‘init_device’:
> plugins/hciops.c:178: error: label ‘done’ defined but not used
> plugins/hciops.c:125: error: unused variable ‘di’
>
> Always check that your patch compiles cleanly with ./bootstrap-configure
> before submitting upstream.

Johan--

Thanks for the tips--I had split-up a combined patch and neglected to 
ensure clean compilation and spacing after the split :-(.

New patch versions coming your way...

Cheers,
David

-- 
David Scherba
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply

* Re: [PATCH] Bluetooth: Process HCI events in a workqueue instead of a tasklet
From: David Vrabel @ 2010-08-10 14:27 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1281446085.12579.212.camel@localhost.localdomain>

Marcel Holtmann wrote:
> Hi David,
> 
>>>> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
>>>> ---
>>>>  include/net/bluetooth/hci_core.h |    2 +
>>>>  net/bluetooth/hci_core.c         |   58 ++++++++++++++++++++++++++++++++-----
>>>>  2 files changed, 52 insertions(+), 8 deletions(-)
>>> so I stuffed this now into bluetooth-testing tree and would like to see
>>> some extra testing exposure. So far this has only been tested by myself.
>>>
>>> If there are no regression then this should make a lot of HCI and L2CAP
>>> handling a lot simple.
>> This may result in packets being processed in a different order to that 
>> which they were received in.
>>
>> e.g., what happens to an ACL packet processed before the connection 
>> complete event for that connection?
> 
> good point. So we would either a) need to disable the RX tasklet when we
> receive an event and schedule it for processing or b) process the ACL
> data also in a workqueue.

I think my preferred solution would be for the rx function called by the 
HCI transport drivers to be called in a thread context.  There should be 
a helper function that is callable in atomic context that queues the 
packets to be processed in a workqueue.

Our UWB drivers already process packets in a thread so would prefer to 
avoid another thread context switch.

Shall I prepare a patch?

David
-- 
David Vrabel, Senior Software Engineer, Drivers
CSR, Churchill House, Cambridge Business Park,  Tel: +44 (0)1223 692562
Cowley Road, Cambridge, CB4 0WZ                 http://www.csr.com/


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom

^ permalink raw reply

* Re: [PATCH] Fix multiple phone number problem in pull vcard
From: Johan Hedberg @ 2010-08-10 14:04 UTC (permalink / raw)
  To: Radoslaw Jablonski; +Cc: linux-bluetooth
In-Reply-To: <1281425000-2029-1-git-send-email-ext-jablonski.radoslaw@nokia.com>

Hi Radek,

On Tue, Aug 10, 2010, Radoslaw Jablonski wrote:
> This fixes problem with pull vcard when contact has more than one home or
> work number defined in tracker - more than one VCARD was generated in
> response for pull vcard request. This was caused by nature of the data
> retrieved from tracker - contact with multiple numbers set was returned as
> many entries with identical id. Previously VCARDs was generated on the fly
> - now added contact-data caching and checking for contact id. VCARD is now
> generated when all responses of tracker were processed - and only one vcard
> is returned for one contact entry.
> ---
>  plugins/phonebook-tracker.c |  130 ++++++++++++++++++++++++++++++++++++-------
>  1 files changed, 109 insertions(+), 21 deletions(-)

The patch is now merged upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] Bluetooth: new sockopt to enter active state when sending data
From: Andrei Emeltchenko @ 2010-08-10 13:53 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1281445643.12579.210.camel@localhost.localdomain>

Hi Marcel,

On Tue, Aug 10, 2010 at 4:07 PM, Marcel Holtmann <marcel@holtmann.org> wrot=
e:
> Hi Andrei,
>
>> From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
>>
>> Patch adds new socket option to enter active state when sending
>> data. Modified version of Fabien Chevalier patch (Sep/2008).
>> Discussions:
>> http://www.spinics.net/lists/bluez-devel/msg00567.html
>> http://www.spinics.net/lists/linux-bluetooth/msg03765.html
>>
>> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
>> ---
>> =A0include/net/bluetooth/hci_core.h | =A0 =A01 +
>> =A0include/net/bluetooth/l2cap.h =A0 =A0| =A0 =A01 +
>> =A0net/bluetooth/hci_conn.c =A0 =A0 =A0 =A0 | =A0 =A07 ++++++-
>> =A0net/bluetooth/l2cap.c =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A03 +++
>> =A04 files changed, 11 insertions(+), 1 deletions(-)
>>
>> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hc=
i_core.h
>> index e42f6ed..477a492 100644
>> --- a/include/net/bluetooth/hci_core.h
>> +++ b/include/net/bluetooth/hci_core.h
>> @@ -178,6 +178,7 @@ struct hci_conn {
>> =A0 =A0 =A0 __u8 =A0 =A0 =A0 =A0 =A0 =A0 auth_type;
>> =A0 =A0 =A0 __u8 =A0 =A0 =A0 =A0 =A0 =A0 sec_level;
>> =A0 =A0 =A0 __u8 =A0 =A0 =A0 =A0 =A0 =A0 power_save;
>> + =A0 =A0 __u8 =A0 =A0 =A0 =A0 =A0 =A0 force_active;
>> =A0 =A0 =A0 __u16 =A0 =A0 =A0 =A0 =A0 =A0disc_timeout;
>> =A0 =A0 =A0 unsigned long =A0 =A0pend;
>>
>> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap=
.h
>> index 7c695bf..0a8ac4c 100644
>> --- a/include/net/bluetooth/l2cap.h
>> +++ b/include/net/bluetooth/l2cap.h
>> @@ -57,6 +57,7 @@ struct l2cap_options {
>> =A0 =A0 =A0 __u8 =A0mode;
>> =A0 =A0 =A0 __u8 =A0fcs;
>> =A0 =A0 =A0 __u8 =A0max_tx;
>> + =A0 =A0 __u8 =A0force_active;
>> =A0 =A0 =A0 __u16 txwin_size;
>> =A0};
>
> this is a clear NAK. You are breaking API and ABI compatibility with
> this change.
>
> Also don't overload the l2cap_options, create a new one.

I have sent new patch. Are other comments from 2008 patch still valid?

Like using SOL_BLUETOOTH and make sockopt for RFCOMM as well.

Regards,
Andrei

^ permalink raw reply

* [PATCHv2] Bluetooth: new sockopt to enter active state when sending data
From: Emeltchenko Andrei @ 2010-08-10 13:48 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>

Patch adds new socket option to enter active state when sending
data. Modified version of Fabien Chevalier patch (Sep/2008).
Discussions:
http://www.spinics.net/lists/bluez-devel/msg00567.html
http://www.spinics.net/lists/linux-bluetooth/msg03765.html

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
---
 include/net/bluetooth/hci_core.h |    1 +
 include/net/bluetooth/l2cap.h    |    2 ++
 net/bluetooth/hci_conn.c         |    7 ++++++-
 net/bluetooth/l2cap.c            |   15 +++++++++++++++
 4 files changed, 24 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e42f6ed..477a492 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -178,6 +178,7 @@ struct hci_conn {
 	__u8             auth_type;
 	__u8             sec_level;
 	__u8             power_save;
+	__u8             force_active;
 	__u16            disc_timeout;
 	unsigned long	 pend;
 
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 7c695bf..540cca7 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -74,6 +74,8 @@ struct l2cap_conninfo {
 #define L2CAP_LM_RELIABLE	0x0010
 #define L2CAP_LM_SECURE		0x0020
 
+#define L2CAP_FORCE_ACTIVE_MODE	0x04
+
 /* L2CAP command codes */
 #define L2CAP_COMMAND_REJ	0x01
 #define L2CAP_CONN_REQ		0x02
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 800b6b9..11fc44a 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -214,6 +214,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
 	conn->auth_type = HCI_AT_GENERAL_BONDING;
 
 	conn->power_save = 1;
+	/* Do not enter active state by default */ 
+	conn->force_active = 0;
 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
 
 	switch (type) {
@@ -505,7 +507,10 @@ void hci_conn_enter_active_mode(struct hci_conn *conn)
 	if (test_bit(HCI_RAW, &hdev->flags))
 		return;
 
-	if (conn->mode != HCI_CM_SNIFF || !conn->power_save)
+	if (conn->mode != HCI_CM_SNIFF)
+		goto timer;
+
+	if (!conn->power_save && !conn->force_active)
 		goto timer;
 
 	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index cf3c407..5328e82 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1909,6 +1909,15 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
 		l2cap_pi(sk)->force_reliable = (opt & L2CAP_LM_RELIABLE);
 		break;
 
+	case L2CAP_FORCE_ACTIVE_MODE:
+		if (get_user(opt, (u32 __user *) optval)) {
+			err = -EFAULT;
+			break;
+		}
+		
+		l2cap_pi(sk)->conn->hcon->force_active = opt;
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
@@ -2058,6 +2067,12 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
 
 		break;
 
+	case L2CAP_FORCE_ACTIVE_MODE:
+		if (put_user(l2cap_pi(sk)->conn->hcon->force_active,
+					(u32 __user *) optval))
+			err = -EFAULT;
+		break;
+
 	default:
 		err = -ENOPROTOOPT;
 		break;
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] Bluetooth: Process HCI events in a workqueue instead of a tasklet
From: Marcel Holtmann @ 2010-08-10 13:14 UTC (permalink / raw)
  To: David Vrabel; +Cc: linux-bluetooth
In-Reply-To: <4C614B01.6030000@csr.com>

Hi David,

> >> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> >> ---
> >>  include/net/bluetooth/hci_core.h |    2 +
> >>  net/bluetooth/hci_core.c         |   58 ++++++++++++++++++++++++++++++++-----
> >>  2 files changed, 52 insertions(+), 8 deletions(-)
> > 
> > so I stuffed this now into bluetooth-testing tree and would like to see
> > some extra testing exposure. So far this has only been tested by myself.
> > 
> > If there are no regression then this should make a lot of HCI and L2CAP
> > handling a lot simple.
> 
> This may result in packets being processed in a different order to that 
> which they were received in.
> 
> e.g., what happens to an ACL packet processed before the connection 
> complete event for that connection?

good point. So we would either a) need to disable the RX tasklet when we
receive an event and schedule it for processing or b) process the ACL
data also in a workqueue.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH] Bluetooth: new sockopt to enter active state when sending data
From: Marcel Holtmann @ 2010-08-10 13:07 UTC (permalink / raw)
  To: Emeltchenko Andrei; +Cc: linux-bluetooth
In-Reply-To: <1281443393-31160-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

Hi Andrei,

> From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
> 
> Patch adds new socket option to enter active state when sending
> data. Modified version of Fabien Chevalier patch (Sep/2008).
> Discussions:
> http://www.spinics.net/lists/bluez-devel/msg00567.html
> http://www.spinics.net/lists/linux-bluetooth/msg03765.html
> 
> Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
> ---
>  include/net/bluetooth/hci_core.h |    1 +
>  include/net/bluetooth/l2cap.h    |    1 +
>  net/bluetooth/hci_conn.c         |    7 ++++++-
>  net/bluetooth/l2cap.c            |    3 +++
>  4 files changed, 11 insertions(+), 1 deletions(-)
> 
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index e42f6ed..477a492 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -178,6 +178,7 @@ struct hci_conn {
>  	__u8             auth_type;
>  	__u8             sec_level;
>  	__u8             power_save;
> +	__u8             force_active;
>  	__u16            disc_timeout;
>  	unsigned long	 pend;
>  
> diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
> index 7c695bf..0a8ac4c 100644
> --- a/include/net/bluetooth/l2cap.h
> +++ b/include/net/bluetooth/l2cap.h
> @@ -57,6 +57,7 @@ struct l2cap_options {
>  	__u8  mode;
>  	__u8  fcs;
>  	__u8  max_tx;
> +	__u8  force_active;
>  	__u16 txwin_size;
>  };

this is a clear NAK. You are breaking API and ABI compatibility with
this change.

Also don't overload the l2cap_options, create a new one.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH] Bluetooth: Process HCI events in a workqueue instead of a tasklet
From: David Vrabel @ 2010-08-10 12:50 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: linux-bluetooth
In-Reply-To: <1281442519.12579.209.camel@localhost.localdomain>

Marcel Holtmann wrote:
> Hi everybody,
> 
>> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
>> ---
>>  include/net/bluetooth/hci_core.h |    2 +
>>  net/bluetooth/hci_core.c         |   58 ++++++++++++++++++++++++++++++++-----
>>  2 files changed, 52 insertions(+), 8 deletions(-)
> 
> so I stuffed this now into bluetooth-testing tree and would like to see
> some extra testing exposure. So far this has only been tested by myself.
> 
> If there are no regression then this should make a lot of HCI and L2CAP
> handling a lot simple.

This may result in packets being processed in a different order to that 
which they were received in.

e.g., what happens to an ACL packet processed before the connection 
complete event for that connection?

David
-- 
David Vrabel, Senior Software Engineer, Drivers
CSR, Churchill House, Cambridge Business Park,  Tel: +44 (0)1223 692562
Cowley Road, Cambridge, CB4 0WZ                 http://www.csr.com/


Member of the CSR plc group of companies. CSR plc registered in England and Wales, registered number 4187346, registered office Churchill House, Cambridge Business Park, Cowley Road, Cambridge, CB4 0WZ, United Kingdom

^ permalink raw reply

* [PATCH] Bluetooth: new sockopt to enter active state when sending data
From: Emeltchenko Andrei @ 2010-08-10 12:29 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>

Patch adds new socket option to enter active state when sending
data. Modified version of Fabien Chevalier patch (Sep/2008).
Discussions:
http://www.spinics.net/lists/bluez-devel/msg00567.html
http://www.spinics.net/lists/linux-bluetooth/msg03765.html

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@nokia.com>
---
 include/net/bluetooth/hci_core.h |    1 +
 include/net/bluetooth/l2cap.h    |    1 +
 net/bluetooth/hci_conn.c         |    7 ++++++-
 net/bluetooth/l2cap.c            |    3 +++
 4 files changed, 11 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index e42f6ed..477a492 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -178,6 +178,7 @@ struct hci_conn {
 	__u8             auth_type;
 	__u8             sec_level;
 	__u8             power_save;
+	__u8             force_active;
 	__u16            disc_timeout;
 	unsigned long	 pend;
 
diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 7c695bf..0a8ac4c 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -57,6 +57,7 @@ struct l2cap_options {
 	__u8  mode;
 	__u8  fcs;
 	__u8  max_tx;
+	__u8  force_active;
 	__u16 txwin_size;
 };
 
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index 800b6b9..b8ea611 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -214,6 +214,8 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
 	conn->auth_type = HCI_AT_GENERAL_BONDING;
 
 	conn->power_save = 1;
+	/* Enter active state by default */ 
+	conn->force_active = 1;
 	conn->disc_timeout = HCI_DISCONN_TIMEOUT;
 
 	switch (type) {
@@ -505,7 +507,10 @@ void hci_conn_enter_active_mode(struct hci_conn *conn)
 	if (test_bit(HCI_RAW, &hdev->flags))
 		return;
 
-	if (conn->mode != HCI_CM_SNIFF || !conn->power_save)
+	if (conn->mode != HCI_CM_SNIFF)
+		goto timer;
+
+	if (!conn->power_save && !conn->force_active)
 		goto timer;
 
 	if (!test_and_set_bit(HCI_CONN_MODE_CHANGE_PEND, &conn->pend)) {
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index cf3c407..a631cf1 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -1863,6 +1863,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
 		opts.mode     = l2cap_pi(sk)->mode;
 		opts.fcs      = l2cap_pi(sk)->fcs;
 		opts.max_tx   = l2cap_pi(sk)->max_tx;
+		opts.force_active = l2cap_pi(sk)->conn->hcon->force_active;
 		opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
 
 		len = min_t(unsigned int, sizeof(opts), optlen);
@@ -1889,6 +1890,7 @@ static int l2cap_sock_setsockopt_old(struct socket *sock, int optname, char __us
 		l2cap_pi(sk)->omtu = opts.omtu;
 		l2cap_pi(sk)->fcs  = opts.fcs;
 		l2cap_pi(sk)->max_tx = opts.max_tx;
+		l2cap_pi(sk)->conn->hcon->force_active = opts.force_active;
 		l2cap_pi(sk)->tx_win = (__u8)opts.txwin_size;
 		break;
 
@@ -2006,6 +2008,7 @@ static int l2cap_sock_getsockopt_old(struct socket *sock, int optname, char __us
 		opts.mode     = l2cap_pi(sk)->mode;
 		opts.fcs      = l2cap_pi(sk)->fcs;
 		opts.max_tx   = l2cap_pi(sk)->max_tx;
+		opts.force_active = l2cap_pi(sk)->conn->hcon->force_active;
 		opts.txwin_size = (__u16)l2cap_pi(sk)->tx_win;
 
 		len = min_t(unsigned int, len, sizeof(opts));
-- 
1.7.0.4


^ permalink raw reply related

* Re: [PATCH] Bluetooth: Process HCI events in a workqueue instead of a tasklet
From: Marcel Holtmann @ 2010-08-10 12:15 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1281323213-30907-1-git-send-email-marcel@holtmann.org>

Hi everybody,

> Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
> ---
>  include/net/bluetooth/hci_core.h |    2 +
>  net/bluetooth/hci_core.c         |   58 ++++++++++++++++++++++++++++++++-----
>  2 files changed, 52 insertions(+), 8 deletions(-)

so I stuffed this now into bluetooth-testing tree and would like to see
some extra testing exposure. So far this has only been tested by myself.

If there are no regression then this should make a lot of HCI and L2CAP
handling a lot simpler.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH] Bluetooth: btmrvl: devices are either BR/EDR or AMPs
From: Marcel Holtmann @ 2010-08-10 12:13 UTC (permalink / raw)
  To: David Vrabel; +Cc: linux-bluetooth
In-Reply-To: <4C607688.9050608@csr.com>

Hi David,

> From 5d16a92e61d8457077d0235d6b7006b824ff6891 Mon Sep 17 00:00:00 2001
> From: David Vrabel <dv02@dv02-laptop.(none)>
> Date: Mon, 9 Aug 2010 22:39:43 +0100
> Subject: [PATCH] Bluetooth: btmrvl: devices are either BR/EDR or AMPs
> 
> Signed-off-by: David Vrabel <david.vrabel@csr.com>
> ---
>  drivers/bluetooth/btmrvl_main.c |    4 ++--
>  1 files changed, 2 insertions(+), 2 deletions(-)

I fixed this up in your original patch.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 1/1] Bluetooth: hidp: Add support for hidraw     HIDIOCGFEATURE  and HIDIOCSFEATURE
From: Marcel Holtmann @ 2010-08-10 12:12 UTC (permalink / raw)
  To: Jiri Kosina
  Cc: Alan Ott, David S Miller, Michael Poole, Bastien Nocera,
	Eric Dumazet, linux-bluetooth, linux-kernel, netdev
In-Reply-To: <alpine.LNX.2.00.1008101344480.29919@pobox.suse.cz>

Hi Jiri,

> > > that the ioctl() API is synchronous is fine to me, however pushing that
> > > down to the transport drivers seems wrong to me. I think the HID core
> > > should be able to handle a fully asynchronous transport driver. I know
> > > that with the USB subsystem you are little bit spoiled here, but for
> > > Bluetooth it is not the case. And in the end even using the asynchronous
> > > USB URB calls would be nice as well.
> > >    
> > 
> > How are the URB calls better than using the synchronous calls? (see below)
> 
> Hi,
> 
> I think this was the last mail in the thread so far, right?
> 
> > > So why not make the core actually wait for responses from the transport
> > > driver.
> > 
> > Because this makes the USB side a lot more complicated, and it would 
> > introduce transport specific code into the core. Further, it would 
> > involve the transport driver calling hidraw with _every_ single packet 
> > it receives. Further, it would have to call hidraw with HANDSHAKE 
> > protocol error packets as well.
> >
> > >   I would make the transport drivers a lot simpler in the long
> > > run.
> > 
> > It would make the USB transport driver and drivers/hid/hidraw much more
> > complicated right now, at the expense of making the BT transport driver
> > marginally simpler (and I'm not even convinced whether it would really be
> > simpler). (see below for more)
> 
> Seconded.
> 
> > >   And I know that most likely besides Bluetooth and USB you won't see
> > > another, but you never know.
> > > 
> > I just don't understand the objection. In each transport type, the waiting
> > will have to be done in a different way. USB and BT are different enough that
> > this is the case already, without having to imagine future buses which use
> > HID. In BT, you have to check each packet which comes back from the BT network
> > to see whether it is the response packet that hidraw is waiting for. Further,
> > you have to check for HANDSHAKE packets indicating protocol error. Where
> > better for this to be done than in hidp? Further, how can this possibly happen
> > in drivers/hid/hidraw, as it doesn't know about the details of bluetooth to
> > make this determination, and why should it? In my last email (
> > http://lkml.org/lkml/2010/7/9/231 ) to which I got no response, I laid out how
> > doing the blocking in drivers/hid/hidraw would only make all the parts except
> > bluetooth more complicated (including the core, and the USB side), and would
> > also introduce bluetooth-specific things into the core.
> > 
> > Further, you're saying that using the asynchronous USB URB calls would be a
> > benefit. How is it a benefit to replace a single function call which does
> > exactly what I want, with a set of asynchronous calls and then adding my own
> > blocking to make it do the same thing? This sounds to me like it would be 1:
> > more text, 2: duplication of code, 3: error prone. I can't understand how this
> > is of benefit. Please explain to me what I'm missing.
> > 
> > In theory, what you're saying makes sense. Making common code and logic
> > actually common is always good. In practice though, in this case, I submit
> > that there really isn't any commonality, and the only way for there to be
> > commonality is to do the USB side the hard way. Further, drivers/hid/hidraw
> > can't wait for a bluetooth packet without having code that's
> > bluetooth-specific. It seems just that simple to me.
> > 
> > I'll give it some more thought, and take another look at the code to see if
> > there's something obvious that I'm missing. If you know what I'm missing in my
> > understanding of the problem, please tell me :)
> 
> Marcel, did you have time to review Alan's explanation a little bit?
> 
> I must say I would really like to have this feature merged, but of course 
> not if you completely disagree .. but then we'll have to find some 
> consensus. Currently Alan's summary above quite aligns with my opinion.

my opinion is still that we should make the core do the async handling.
I think that we let USB dictate how APIs for HID should look like.

However that is maybe fine anyway since the Bluetooth HID guys where not
really inventive since they copying USB HID for the better and mostly
for the worst. Especially since Bluetooth doesn't have the endpoint
direction limits like USB does. Anyhow, just get the patches re-based
and re-submitted and I can have a second look.

Regards

Marcel



^ permalink raw reply

* Re: [PATCH 1/1] Bluetooth: hidp: Add support for hidraw     HIDIOCGFEATURE  and HIDIOCSFEATURE
From: Jiri Kosina @ 2010-08-10 11:46 UTC (permalink / raw)
  To: Alan Ott
  Cc: Marcel Holtmann, David S Miller, Michael Poole, Bastien Nocera,
	Eric Dumazet, linux-bluetooth, linux-kernel, netdev
In-Reply-To: <4C4878C2.9000903@signal11.us>

On Thu, 22 Jul 2010, Alan Ott wrote:

> > that the ioctl() API is synchronous is fine to me, however pushing that
> > down to the transport drivers seems wrong to me. I think the HID core
> > should be able to handle a fully asynchronous transport driver. I know
> > that with the USB subsystem you are little bit spoiled here, but for
> > Bluetooth it is not the case. And in the end even using the asynchronous
> > USB URB calls would be nice as well.
> >    
> 
> How are the URB calls better than using the synchronous calls? (see below)

Hi,

I think this was the last mail in the thread so far, right?

> > So why not make the core actually wait for responses from the transport
> > driver.
> 
> Because this makes the USB side a lot more complicated, and it would 
> introduce transport specific code into the core. Further, it would 
> involve the transport driver calling hidraw with _every_ single packet 
> it receives. Further, it would have to call hidraw with HANDSHAKE 
> protocol error packets as well.
>
> >   I would make the transport drivers a lot simpler in the long
> > run.
> 
> It would make the USB transport driver and drivers/hid/hidraw much more
> complicated right now, at the expense of making the BT transport driver
> marginally simpler (and I'm not even convinced whether it would really be
> simpler). (see below for more)

Seconded.

> >   And I know that most likely besides Bluetooth and USB you won't see
> > another, but you never know.
> > 
> I just don't understand the objection. In each transport type, the waiting
> will have to be done in a different way. USB and BT are different enough that
> this is the case already, without having to imagine future buses which use
> HID. In BT, you have to check each packet which comes back from the BT network
> to see whether it is the response packet that hidraw is waiting for. Further,
> you have to check for HANDSHAKE packets indicating protocol error. Where
> better for this to be done than in hidp? Further, how can this possibly happen
> in drivers/hid/hidraw, as it doesn't know about the details of bluetooth to
> make this determination, and why should it? In my last email (
> http://lkml.org/lkml/2010/7/9/231 ) to which I got no response, I laid out how
> doing the blocking in drivers/hid/hidraw would only make all the parts except
> bluetooth more complicated (including the core, and the USB side), and would
> also introduce bluetooth-specific things into the core.
> 
> Further, you're saying that using the asynchronous USB URB calls would be a
> benefit. How is it a benefit to replace a single function call which does
> exactly what I want, with a set of asynchronous calls and then adding my own
> blocking to make it do the same thing? This sounds to me like it would be 1:
> more text, 2: duplication of code, 3: error prone. I can't understand how this
> is of benefit. Please explain to me what I'm missing.
> 
> In theory, what you're saying makes sense. Making common code and logic
> actually common is always good. In practice though, in this case, I submit
> that there really isn't any commonality, and the only way for there to be
> commonality is to do the USB side the hard way. Further, drivers/hid/hidraw
> can't wait for a bluetooth packet without having code that's
> bluetooth-specific. It seems just that simple to me.
> 
> I'll give it some more thought, and take another look at the code to see if
> there's something obvious that I'm missing. If you know what I'm missing in my
> understanding of the problem, please tell me :)

Marcel, did you have time to review Alan's explanation a little bit?

I must say I would really like to have this feature merged, but of course 
not if you completely disagree .. but then we'll have to find some 
consensus. Currently Alan's summary above quite aligns with my opinion.

Thanks,

-- 
Jiri Kosina
SUSE Labs, Novell Inc.

^ permalink raw reply

* Interlaced page scan
From: Krishnan @ 2010-08-10  8:45 UTC (permalink / raw)
  To: linux-bluetooth

Hi,

Is there a way to enable interlaced page scan in BlueZ? I know 
hciconfig has an option to enable only interlaced inquiry scan.

Regards,
Krishnan

^ permalink raw reply

* Re: [PATCH] Changes in HDP API.
From: José Antonio Santos Cadenas @ 2010-08-10  8:01 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1281016183-4547-1-git-send-email-santoscadenas@gmail.com>

Hi all,

El Thursday 05 August 2010 15:49:43 Jose Antonio Santos Cadenas escribió:
> Now the connection is made directly to a device and bluetoothd daemon
> guess the PSM connection and the MDEPID based on the data get from the
> SDP record.
> ---
>  doc/health-api.txt |  105
> ++++++++++++++++++++-------------------------------- 1 files changed, 40
> insertions(+), 65 deletions(-)
> 
> diff --git a/doc/health-api.txt b/doc/health-api.txt
> index f469df3..89df8bd 100644
> --- a/doc/health-api.txt
> +++ b/doc/health-api.txt
> @@ -14,12 +14,9 @@ Object path	/org/bluez/
> 
>  Methods:
> 
> -	object	CreateApplication(dict config, object agent)
> +	object	CreateApplication(dict config)
> 
> -		Returns the path of the new registered application. The agent
> -		parameter is the path of the object with the callbacks to
> -		notify events (see org.bluez.HealthAgent at the end
> -		of this document).
> +		Returns the path of the new registered application.
> 
>  		Dict is defined as bellow:
>  		{
> @@ -39,32 +36,33 @@ Methods:
> 
>  		Closes the HDP application identified by the object path. Also
>  		application will be closed if the process that started it leaves
> -		the bus.
> +		the bus. Only the creator of the application will be able to
> +		destroy it.
> 
>  		Possible errors: org.bluez.Error.InvalidArguments
>  				org.bluez.Error.NotFound
> +				org.bluez.Error.NotAllowed
> 
>  --------------------------------------------------------------------------
> ------
> 
>  Service		org.bluez
> -Interface	org.bluez.HealthApplication
> -Object path	[variable prefix]/health_app_ZZZZ
> +Interface	org.bluez.HealthDevice
> +Object path	[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX
> 
>  Methods:
> 
> -	void Echo(object service)
> +	Boolean Echo()
> 
>  		Sends an echo petition to the remote service. Returns True if
>  		response matches with the buffer sent. If some error is detected
> -		False value is returned and the associated MCL is closed.
> +		False value is returned.
> 
>  		Possible errors: org.bluez.Error.InvalidArguments
>  				org.bluez.Error.OutOfRange
> 
> -	object CreateChannel(object service, string type)
> +	object CreateChannel(object application, string configuration)
> 
> -		Creates a new data channel with the indicated config to the
> -		remote Service.
> +		Creates a new data channel.
>  		The configuration should indicate the channel quality of
>  		service using one of this values "Reliable", "Streaming", "Any".
> 
> @@ -76,16 +74,27 @@ Methods:
> 
>  	void DestroyChannel(object channel)
> 
> -		Destroys the data channel object.
> +		Destroys the data channel object. Only the creator of the
> +		channel or the creator of the HealtApplication that received the
> +		data channel will be able to destroy it
> 
>  		Possible errors: org.bluez.Error.InvalidArguments
> -				orb.bluez.Error.NotFound
> +				org.bluez.Error.NotFound
> +				org.bluez.Error.NotAllowed
> 
> ---------------------------------------------------------------------------
> ------ +Signals:
> 
> -Service		org.bluez
> -Interface	org.bluez.HealthService
> -Object path	[variable
> prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/hdp_YYYY +	void
> ChannelConnected(object channel)
> +
> +		This signal is launched when a new data channel is created or
> +		when a known data channel is reconnected.
> +
> +	void ChannelDeleted(object channel)
> +
> +		This signal is launched when a data channel is deleted.
> +
> +		After this signal the data channel path will not be valid and
> +		its path can be reused for future data channels.
> 
>  --------------------------------------------------------------------------
> ------
> 
> @@ -94,6 +103,9 @@ Interface	org.bluez.HealthChannel
>  Object path	[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/
>  							hdp_YYYY/channel_ZZ
> 
> +Only the process that created the data channel or the creator of the
> +HealthApplication that received it will be able to call this methods.
> +
>  Methods:
> 
>  	dict GetProperties()
> @@ -101,17 +113,23 @@ Methods:
>  		Returns all properties for the interface. See the properties
>  		section for available properties.
> 
> +		Posible errors: org.bluez.Error.NotAllowed
> +
>  	fd Acquire()
> 
>  		Returns the file descriptor for this data channel. If the data
>  		channel is not connected it will also reconnect.
> 
>  		Possible errors: org.bluez.Error.NotConnected
> +				org.bluez.Error.NotAllowed
> 
>  	void Release()
> 
>  		Releases the fd. Application should also need to close() it.
> 
> +		Possible errors: org.bluez.Error.NotAcquired
> +				org.bluez.Error.NotAllowed
> +
>  Properties:
> 
>  	string Type (read only)
> @@ -119,50 +137,7 @@ Properties:
>  		The quality of service of the data channel. ("Reliable" or
>  		"Streaming")
> 
> -	object Service (read only)
> -
> -		Identifies the Remote Service that is connected with. Maps with
> -		a HealthService object.
> -
> -HealthAgent hierarchy
> -=====================
> -
> -(this object is implemented by the HDP user in order to receive
> notifications) -
> -Service		unique name
> -Interface	org.bluez.HealthAgent
> -Object path	freely definable
> -
> -Methods:
> -
> -	void Release()
> -
> -		This method gets called when the service daemon unregisters the
> -		agent. An agent can use it to do cleanup tasks. There is no need
> -		to unregister the agent, because when this method gets called it
> -		has already been unregistered.
> -
> -	void ServiceDiscovered(object service)
> -
> -		This method is called when a device containing an HDP
> -		application is paired or when the method Update of the
> -		HealthManager is called and new HealthServices are discovered.
> -		The method will be called once for each HealthService.
> -
> -	void ServiceRemoved(object service)
> -
> -		This is called if during an Update some HealthServices
> -		have disappeared. The method is called once for each removed
> -		HealthService.
> -
> -	void ChannelConnected(object channel)
> -
> -		This method is called when a new data channel is created or when
> -		a known data channel is reconnected.
> -
> -	void ChannelDeleted(object channel)
> -
> -		This method is called when a data channel is deleted.
> +	object Device (read only)
> 
> -		After this call the data channel path will not be valid and can
> -		be reused for future creation of data channels.
> +		Identifies the Remote Device that is connected with. Maps with
> +		a HealthDevice object.


Any more comments about this? Are there any extra things to talk about? It 
will be great to fix this issues so we can continue developing the plugin.

Thanks.

Jose

^ permalink raw reply

* Re: Question about BlueZ licenses (LGPL and Apache)
From: Luiz Augusto von Dentz @ 2010-08-10  7:49 UTC (permalink / raw)
  To: Pavan Savoy; +Cc: Madhavi Manchala, linux-bluetooth
In-Reply-To: <AANLkTikFQiEEVKA=9UnxzeunAPEviWQnjYcH=q6rfhjA@mail.gmail.com>

Hi,

On Mon, Aug 9, 2010 at 10:37 PM, Pavan Savoy <pavan_savoy@sify.com> wrote:
> As long as we are updating, can the liba2dp be abstracted out of not
> only the sbc encoding part but also the sending over UART part (as in
> transport ...)
>
> chips are getting smarter and the sbc codecs are moving to either a
> co-processor/dsp or even inside the BT chip itself, so we might have
> to send the PCM raw data somewhere else for the dsp to encode to sbc
> and send it over the air ...
>
> currently the data (sbc/pcm) and the control (connection
> establishment) is too tightly sort of coded in together.. isn't it ?
>
> for something like the above to happen our liba2dp had to be almost
> re-written ...

Im afraid liba2dp is some android specific thing, not upstream, and as
I said before upstream is probably going to use dbus to pass the fd
around, so this is probably not relevant here.

-- 
Luiz Augusto von Dentz
Computer Engineer

^ permalink raw reply

* [PATCH] Fix multiple phone number problem in pull vcard
From: Radoslaw Jablonski @ 2010-08-10  7:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Radoslaw Jablonski

This fixes problem with pull vcard when contact has more than one home or
work number defined in tracker - more than one VCARD was generated in
response for pull vcard request. This was caused by nature of the data
retrieved from tracker - contact with multiple numbers set was returned as
many entries with identical id. Previously VCARDs was generated on the fly
- now added contact-data caching and checking for contact id. VCARD is now
generated when all responses of tracker were processed - and only one vcard
is returned for one contact entry.
---
 plugins/phonebook-tracker.c |  130 ++++++++++++++++++++++++++++++++++++-------
 1 files changed, 109 insertions(+), 21 deletions(-)

diff --git a/plugins/phonebook-tracker.c b/plugins/phonebook-tracker.c
index f2b9649..3a90d30 100644
--- a/plugins/phonebook-tracker.c
+++ b/plugins/phonebook-tracker.c
@@ -43,6 +43,9 @@
 #define TRACKER_RESOURCES_INTERFACE "org.freedesktop.Tracker1.Resources"
 
 #define TRACKER_DEFAULT_CONTACT_ME "http://www.semanticdesktop.org/ontologies/2007/03/22/nco#default-contact-me"
+#define CONTACTS_ID_COL 19
+#define PHONE_ID_HOME 0
+#define PHONE_ID_WORK 3
 
 #define CONTACTS_QUERY_ALL						\
 	"SELECT nco:phoneNumber(?h) nco:fullname(?c) "			\
@@ -275,13 +278,18 @@ struct pending_reply {
 	int num_fields;
 };
 
+struct contact_data {
+	char *id;
+	struct phonebook_contact *contact;
+};
+
 struct phonebook_data {
-	GString *vcards;
 	phonebook_cb cb;
 	void *user_data;
 	int index;
 	gboolean vcardentry;
 	const struct apparam_field *params;
+	GSList *contacts;
 };
 
 struct cache_data {
@@ -545,20 +553,103 @@ static void set_call_type(struct phonebook_contact *contact,
 	contact->datetime = iso8601_utc_to_localtime(datetime);
 }
 
+static struct phonebook_contact *find_contact(GSList *contacts, const char *id)
+{
+	GSList *l;
+	struct contact_data *c_data;
+
+	for (l = contacts; l; l = l->next) {
+		c_data = l->data;
+		if (g_strcmp0(c_data->id, id) == 0)
+			return c_data->contact;
+	}
+
+	return NULL;
+}
+
+static struct phonebook_number *find_phone(GSList *numbers, const char *phone,
+		int type)
+{
+	GSList *l;
+	struct phonebook_number *pb_num;
+
+	for (l = numbers; l; l = l->next) {
+		pb_num = l->data;
+		/* Returning phonebook number if phone values and type values
+		 * are equal */
+		if (g_strcmp0(pb_num->tel, phone) == 0 && pb_num->type == type)
+			return pb_num;
+	}
+
+	return NULL;
+}
+
+static void add_phone_number(struct phonebook_contact *contact,
+		const char *phone, int type)
+{
+	struct phonebook_number *number;
+
+	if (phone == NULL || strlen(phone) == 0)
+		return;
+
+	/* Not adding number if there is already added with the same value */
+	if (find_phone(contact->numbers, phone, type))
+		return;
+
+	number = g_new0(struct phonebook_number, 1);
+	number->tel = g_strdup(phone);
+	number->type = type;
+
+	contact->numbers = g_slist_append(contact->numbers, number);
+}
+
+static GString *gen_vcards(GSList *contacts,
+		const struct apparam_field *params)
+{
+	GSList *l;
+	GString *vcards;
+	struct contact_data *c_data;
+
+	vcards = g_string_new(NULL);
+
+	/* Generating VCARD string from contacts and freeing used contacts */
+	for (l = contacts; l; l = l->next) {
+		c_data = l->data;
+		phonebook_add_contact(vcards, c_data->contact,
+					params->filter, params->format);
+
+		g_free(c_data->id);
+		phonebook_contact_free(c_data->contact);
+	}
+
+	return vcards;
+}
+
 static void pull_contacts(char **reply, int num_fields, void *user_data)
 {
 	struct phonebook_data *data = user_data;
 	const struct apparam_field *params = data->params;
 	struct phonebook_contact *contact;
-	struct phonebook_number *number;
-	GString *vcards = data->vcards;
+	struct contact_data *contact_data;
+	GString *vcards;
 	int last_index, i;
+	gboolean cdata_present = FALSE;
 
 	DBG("reply %p", reply);
 
 	if (reply == NULL)
 		goto done;
 
+	/* Trying to find contact in recently added contacts. It is needed for
+	 * contacts that have more than one telephone number filled */
+	contact = find_contact(data->contacts, reply[CONTACTS_ID_COL]);
+
+	/* If contact is already created then adding only new phone numbers */
+	if (contact) {
+		cdata_present = TRUE;
+		goto add_numbers;
+	}
+
 	/* We are doing a PullvCardEntry, no need for those checks */
 	if (data->vcardentry)
 		goto add_entry;
@@ -603,33 +694,32 @@ add_entry:
 
 	set_call_type(contact, reply[16], reply[17], reply[18]);
 
-	number = g_new0(struct phonebook_number, 1);
-	number->tel = g_strdup(reply[0]);
-	number->type = 0; /* HOME */
-
-	contact->numbers = g_slist_append(contact->numbers, number);
-
-	/* Has WORK Phonenumber */
-	if (strlen(reply[8])) {
-		number = g_new0(struct phonebook_number, 1);
-		number->tel = g_strdup(reply[8]);
-		number->type = 3; /* WORK */
-
-		contact->numbers = g_slist_append(contact->numbers, number);
-	}
+add_numbers:
+	/* Adding phone numbers to contact struct */
+	add_phone_number(contact, reply[0], PHONE_ID_HOME);
+	add_phone_number(contact, reply[8], PHONE_ID_WORK);
 
 	DBG("contact %p", contact);
 
-	phonebook_add_contact(vcards, contact, params->filter, params->format);
-	phonebook_contact_free(contact);
+	/* Adding contacts data to wrapper struct - this data will be used to
+	 * generate vcard list */
+	if (!cdata_present) {
+		contact_data = g_new0(struct contact_data, 1);
+		contact_data->contact = contact;
+		contact_data->id = g_strdup(reply[CONTACTS_ID_COL]);
+		data->contacts = g_slist_append(data->contacts, contact_data);
+	}
 
 	return;
 
 done:
+	vcards = gen_vcards(data->contacts, params);
+
 	if (num_fields == 0)
 		data->cb(vcards->str, vcards->len, data->index, 0,
 							data->user_data);
 
+	g_slist_free(data->contacts);
 	g_string_free(vcards, TRUE);
 	g_free(data);
 }
@@ -775,7 +865,6 @@ int phonebook_pull(const char *name, const struct apparam_field *params,
 		return -ENOENT;
 
 	data = g_new0(struct phonebook_data, 1);
-	data->vcards = g_string_new(NULL);
 	data->params = params;
 	data->user_data = user_data;
 	data->cb = cb;
@@ -794,7 +883,6 @@ int phonebook_get_entry(const char *folder, const char *id,
 	DBG("folder %s id %s", folder, id);
 
 	data = g_new0(struct phonebook_data, 1);
-	data->vcards = g_string_new(NULL);
 	data->user_data = user_data;
 	data->params = params;
 	data->cb = cb;
-- 
1.7.0.4


^ 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