Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH v2 2/4] Bluetooth: Allow for NULL data in mgmt_pending_add
From: Szymon Janc @ 2011-03-01 17:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1299000216-6570-1-git-send-email-szymon.janc@tieto.com>

Since index is in mgmt_hdr it is possible to have mgmt command with
no parameters that still needs to add itself to pending list.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 net/bluetooth/mgmt.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index bde42a5..97d7240 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -235,7 +235,8 @@ static struct pending_cmd *mgmt_pending_add(struct sock *sk, u16 opcode,
 		return NULL;
 	}
 
-	memcpy(cmd->cmd_params, data, len);
+	if (data)
+		memcpy(cmd->cmd_params, data, len);
 
 	cmd->sk = sk;
 	sock_hold(sk);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 3/4] Bluetooth: Add read_local_oob_data management command
From: Szymon Janc @ 2011-03-01 17:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1299000216-6570-1-git-send-email-szymon.janc@tieto.com>

This patch adds a command to read local OOB data to the managment interface.
The command maps directly to the Read Local OOB Data HCI command.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 include/net/bluetooth/hci.h      |    7 +++
 include/net/bluetooth/hci_core.h |    2 +
 include/net/bluetooth/mgmt.h     |    6 +++
 net/bluetooth/hci_event.c        |   15 +++++++
 net/bluetooth/mgmt.c             |   85 ++++++++++++++++++++++++++++++++++++++
 5 files changed, 115 insertions(+), 0 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index ec6acf2..20840dc 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -611,6 +611,13 @@ struct hci_cp_write_ssp_mode {
 	__u8     mode;
 } __packed;
 
+#define HCI_OP_READ_LOCAL_OOB_DATA		0x0c57
+struct hci_rp_read_local_oob_data {
+	__u8     status;
+	__u8     hash[16];
+	__u8     randomizer[16];
+} __packed;
+
 #define HCI_OP_READ_INQ_RSP_TX_POWER	0x0c58
 
 #define HCI_OP_READ_LOCAL_VERSION	0x1001
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 441dadb..c8b7ee6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -767,6 +767,8 @@ int mgmt_user_confirm_reply_complete(u16 index, bdaddr_t *bdaddr, u8 status);
 int mgmt_user_confirm_neg_reply_complete(u16 index, bdaddr_t *bdaddr,
 								u8 status);
 int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status);
+int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
+								u8 status);
 
 /* HCI info for socket */
 #define hci_pi(sk) ((struct hci_pinfo *) sk)
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 5fabfa8..916b1c6 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -167,6 +167,12 @@ struct mgmt_rp_user_confirm_reply {
 
 #define MGMT_OP_USER_CONFIRM_NEG_REPLY	0x0016
 
+#define MGMT_OP_READ_LOCAL_OOB_DATA	0x0017
+struct mgmt_rp_read_local_oob_data {
+	__u8 hash[16];
+	__u8 randomizer[16];
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16 opcode;
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 3fbfa50..4faab87 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -807,6 +807,17 @@ static void hci_cc_user_confirm_reply(struct hci_dev *hdev, struct sk_buff *skb)
 								rp->status);
 }
 
+static void hci_cc_read_local_oob_data_reply(struct hci_dev *hdev,
+							struct sk_buff *skb)
+{
+	struct hci_rp_read_local_oob_data *rp = (void *) skb->data;
+
+	BT_DBG("%s status 0x%x", hdev->name, rp->status);
+
+	mgmt_read_local_oob_data_reply_complete(hdev->id, rp->hash,
+						rp->randomizer, rp->status);
+}
+
 static void hci_cc_user_confirm_neg_reply(struct hci_dev *hdev,
 							struct sk_buff *skb)
 {
@@ -1749,6 +1760,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		hci_cc_pin_code_neg_reply(hdev, skb);
 		break;
 
+	case HCI_OP_READ_LOCAL_OOB_DATA:
+		hci_cc_read_local_oob_data_reply(hdev, skb);
+		break;
+
 	case HCI_OP_LE_READ_BUFFER_SIZE:
 		hci_cc_le_read_buffer_size(hdev, skb);
 		break;
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 97d7240..ba43b85 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1259,6 +1259,57 @@ failed:
 	return err;
 }
 
+static int read_local_oob_data(struct sock *sk, u16 index)
+{
+	struct hci_dev *hdev;
+	struct pending_cmd *cmd;
+	int err;
+
+	BT_DBG("hci%u", index);
+
+	hdev = hci_dev_get(index);
+	if (!hdev)
+		return cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+									ENODEV);
+
+	hci_dev_lock_bh(hdev);
+
+	if (!test_bit(HCI_UP, &hdev->flags)) {
+		err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+								ENETDOWN);
+		goto unlock;
+	}
+
+	if (!(hdev->features[6] & LMP_SIMPLE_PAIR)) {
+		err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+								EOPNOTSUPP);
+		goto unlock;
+	}
+
+	if (mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index)) {
+		err = cmd_status(sk, index, MGMT_OP_READ_LOCAL_OOB_DATA, EBUSY);
+		goto unlock;
+	}
+
+	cmd = mgmt_pending_add(sk, MGMT_OP_READ_LOCAL_OOB_DATA, index, NULL, 0);
+
+	if (!cmd) {
+		err = -ENOMEM;
+		goto unlock;
+	}
+
+	err = hci_send_cmd(hdev, HCI_OP_READ_LOCAL_OOB_DATA, 0, NULL);
+
+	if (err < 0)
+		mgmt_pending_remove(cmd);
+
+unlock:
+	hci_dev_unlock_bh(hdev);
+	hci_dev_put(hdev);
+
+	return err;
+}
+
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 {
 	unsigned char *buf;
@@ -1354,6 +1405,10 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 	case MGMT_OP_USER_CONFIRM_NEG_REPLY:
 		err = user_confirm_reply(sk, index, buf + sizeof(*hdr), len, 0);
 		break;
+	case MGMT_OP_READ_LOCAL_OOB_DATA:
+		err = read_local_oob_data(sk, index);
+		break;
+
 	default:
 		BT_DBG("Unknown op %u", opcode);
 		err = cmd_status(sk, index, opcode, 0x01);
@@ -1652,3 +1707,33 @@ int mgmt_auth_failed(u16 index, bdaddr_t *bdaddr, u8 status)
 
 	return mgmt_event(MGMT_EV_AUTH_FAILED, index, &ev, sizeof(ev), NULL);
 }
+
+int mgmt_read_local_oob_data_reply_complete(u16 index, u8 *hash, u8 *randomizer,
+								u8 status)
+{
+	struct pending_cmd *cmd;
+	int err;
+
+	BT_DBG("hci%u status %u", index, status);
+
+	cmd = mgmt_pending_find(MGMT_OP_READ_LOCAL_OOB_DATA, index);
+	if (!cmd)
+		return -ENOENT;
+
+	if (status) {
+		err = cmd_status(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+									EIO);
+	} else {
+		struct mgmt_rp_read_local_oob_data rp;
+
+		memcpy(rp.hash, hash, 16);
+		memcpy(rp.randomizer, randomizer, 16);
+
+		err = cmd_complete(cmd->sk, index, MGMT_OP_READ_LOCAL_OOB_DATA,
+							&rp, sizeof(rp));
+	}
+
+	mgmt_pending_remove(cmd);
+
+	return err;
+}
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH v2 4/4] Bluetooth: Add add/remove_remote_oob_data management commands
From: Szymon Janc @ 2011-03-01 17:23 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Szymon Janc
In-Reply-To: <1299000216-6570-1-git-send-email-szymon.janc@tieto.com>

This patch adds commands to add and remove remote OOB data to the managment
interface. Remote data is stored in kernel and used by corresponding HCI
commands and events (also implemented in this patch) when needed.

Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
---
 include/net/bluetooth/hci.h      |   19 +++++++++
 include/net/bluetooth/hci_core.h |   16 ++++++++
 include/net/bluetooth/mgmt.h     |   12 ++++++
 net/bluetooth/hci_core.c         |   76 ++++++++++++++++++++++++++++++++++++++
 net/bluetooth/hci_event.c        |   41 ++++++++++++++++++++-
 net/bluetooth/mgmt.c             |   75 +++++++++++++++++++++++++++++++++++++
 6 files changed, 238 insertions(+), 1 deletions(-)

diff --git a/include/net/bluetooth/hci.h b/include/net/bluetooth/hci.h
index 20840dc..b37ed33 100644
--- a/include/net/bluetooth/hci.h
+++ b/include/net/bluetooth/hci.h
@@ -426,6 +426,20 @@ struct hci_rp_user_confirm_reply {
 
 #define HCI_OP_USER_CONFIRM_NEG_REPLY	0x042d
 
+
+#define HCI_OP_REMOTE_OOB_DATA_REPLY	0x0430
+struct hci_cp_remote_oob_data_reply {
+	bdaddr_t bdaddr;
+	__u8     hash[16];
+	__u8     randomizer[16];
+} __packed;
+
+#define HCI_OP_REMOTE_OOB_DATA_NEG_REPLY	0x0433
+struct hci_cp_remote_oob_data_neg_reply {
+	bdaddr_t bdaddr;
+} __packed;
+
+
 #define HCI_OP_IO_CAPABILITY_NEG_REPLY	0x0434
 struct hci_cp_io_capability_neg_reply {
 	bdaddr_t bdaddr;
@@ -960,6 +974,11 @@ struct hci_ev_user_confirm_req {
 	__le32		passkey;
 } __packed;
 
+#define HCI_EV_REMOTE_OOB_DATA_REQUEST	0x35
+struct hci_ev_remote_oob_data_request {
+	bdaddr_t bdaddr;
+} __packed;
+
 #define HCI_EV_SIMPLE_PAIR_COMPLETE	0x36
 struct hci_ev_simple_pair_complete {
 	__u8     status;
diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index c8b7ee6..0f1e1d6 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -82,6 +82,13 @@ struct link_key {
 	u8 pin_len;
 };
 
+struct oob_data {
+	struct list_head list;
+	bdaddr_t bdaddr;
+	u8 hash[16];
+	u8 randomizer[16];
+};
+
 #define NUM_REASSEMBLY 4
 struct hci_dev {
 	struct list_head list;
@@ -169,6 +176,8 @@ struct hci_dev {
 
 	struct list_head	link_keys;
 
+	struct list_head	remote_oob_data;
+
 	struct hci_dev_stats	stat;
 
 	struct sk_buff_head	driver_init;
@@ -505,6 +514,13 @@ int hci_add_link_key(struct hci_dev *hdev, int new_key, bdaddr_t *bdaddr,
 						u8 *key, u8 type, u8 pin_len);
 int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr);
 
+int hci_remote_oob_data_clear(struct hci_dev *hdev);
+struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
+							bdaddr_t *bdaddr);
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
+								u8 *randomizer);
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr);
+
 void hci_del_off_timer(struct hci_dev *hdev);
 
 void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb);
diff --git a/include/net/bluetooth/mgmt.h b/include/net/bluetooth/mgmt.h
index 916b1c6..ebe288c 100644
--- a/include/net/bluetooth/mgmt.h
+++ b/include/net/bluetooth/mgmt.h
@@ -173,6 +173,18 @@ struct mgmt_rp_read_local_oob_data {
 	__u8 randomizer[16];
 } __packed;
 
+#define MGMT_OP_ADD_REMOTE_OOB_DATA	0x0018
+struct mgmt_cp_add_remote_oob_data {
+	bdaddr_t bdaddr;
+	__u8 hash[16];
+	__u8 randomizer[16];
+} __packed;
+
+#define MGMT_OP_REMOVE_REMOTE_OOB_DATA	0x0019
+struct mgmt_cp_remove_remote_oob_data {
+	bdaddr_t bdaddr;
+} __packed;
+
 #define MGMT_EV_CMD_COMPLETE		0x0001
 struct mgmt_ev_cmd_complete {
 	__le16 opcode;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b372fb8..a1d2263 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -1077,6 +1077,79 @@ static void hci_cmd_timer(unsigned long arg)
 	tasklet_schedule(&hdev->cmd_task);
 }
 
+struct oob_data *hci_find_remote_oob_data(struct hci_dev *hdev,
+							bdaddr_t *bdaddr)
+{
+	struct list_head *p;
+
+	list_for_each(p, &hdev->remote_oob_data) {
+		struct oob_data *data;
+
+		data = list_entry(p, struct oob_data, list);
+
+		if (bacmp(bdaddr, &data->bdaddr) == 0)
+			return data;
+	}
+
+	return NULL;
+}
+
+int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
+{
+	struct oob_data *data;
+
+	data = hci_find_remote_oob_data(hdev, bdaddr);
+	if (!data)
+		return -ENOENT;
+
+	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
+
+	list_del(&data->list);
+	kfree(data);
+
+	return 0;
+}
+
+int hci_remote_oob_data_clear(struct hci_dev *hdev)
+{
+	struct list_head *p, *n;
+
+	list_for_each_safe(p, n, &hdev->remote_oob_data) {
+		struct oob_data *data;
+
+		data = list_entry(p, struct oob_data, list);
+
+		list_del(p);
+		kfree(data);
+	}
+
+	return 0;
+}
+
+int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
+								u8 *randomizer)
+{
+	struct oob_data *data;
+
+	data = hci_find_remote_oob_data(hdev, bdaddr);
+
+	if (!data) {
+		data = kmalloc(sizeof(*data), GFP_ATOMIC);
+		if (!data)
+			return -ENOMEM;
+
+		bacpy(&data->bdaddr, bdaddr);
+		list_add(&data->list, &hdev->remote_oob_data);
+	}
+
+	memcpy(data->hash, hash, 16);
+	memcpy(data->randomizer, randomizer, 16);
+
+	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
+
+	return 0;
+}
+
 /* Register HCI device */
 int hci_register_dev(struct hci_dev *hdev)
 {
@@ -1141,6 +1214,8 @@ int hci_register_dev(struct hci_dev *hdev)
 
 	INIT_LIST_HEAD(&hdev->link_keys);
 
+	INIT_LIST_HEAD(&hdev->remote_oob_data);
+
 	INIT_WORK(&hdev->power_on, hci_power_on);
 	INIT_WORK(&hdev->power_off, hci_power_off);
 	setup_timer(&hdev->off_timer, hci_auto_off, (unsigned long) hdev);
@@ -1220,6 +1295,7 @@ int hci_unregister_dev(struct hci_dev *hdev)
 	hci_blacklist_clear(hdev);
 	hci_uuids_clear(hdev);
 	hci_link_keys_clear(hdev);
+	hci_remote_oob_data_clear(hdev);
 	hci_dev_unlock_bh(hdev);
 
 	__hci_dev_put(hdev);
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 4faab87..955b86a 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -2368,9 +2368,14 @@ static inline void hci_io_capa_request_evt(struct hci_dev *hdev, struct sk_buff
 
 		bacpy(&cp.bdaddr, &ev->bdaddr);
 		cp.capability = conn->io_capability;
-		cp.oob_data = 0;
 		cp.authentication = hci_get_auth_req(conn);
 
+		if ((conn->out == 1 || conn->remote_oob == 0x01) &&
+				hci_find_remote_oob_data(hdev, &conn->dst))
+			cp.oob_data = 0x01;
+		else
+			cp.oob_data = 0x00;
+
 		hci_send_cmd(hdev, HCI_OP_IO_CAPABILITY_REPLY,
 							sizeof(cp), &cp);
 	} else {
@@ -2468,6 +2473,37 @@ static inline void hci_remote_host_features_evt(struct hci_dev *hdev, struct sk_
 	hci_dev_unlock(hdev);
 }
 
+static inline void hci_remote_oob_data_request_evt(struct hci_dev *hdev,
+							struct sk_buff *skb)
+{
+	struct hci_ev_remote_oob_data_request *ev = (void *) skb->data;
+	struct oob_data *data;
+
+	BT_DBG("%s", hdev->name);
+
+	hci_dev_lock(hdev);
+
+	data = hci_find_remote_oob_data(hdev, &ev->bdaddr);
+	if (data) {
+		struct hci_cp_remote_oob_data_reply cp;
+
+		bacpy(&cp.bdaddr, &ev->bdaddr);
+		memcpy(cp.hash, data->hash, 16);
+		memcpy(cp.randomizer, data->randomizer, 16);
+
+		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_REPLY, sizeof(cp),
+									&cp);
+	} else {
+		struct hci_cp_remote_oob_data_neg_reply cp;
+
+		bacpy(&cp.bdaddr, &ev->bdaddr);
+		hci_send_cmd(hdev, HCI_OP_REMOTE_OOB_DATA_NEG_REPLY, sizeof(cp),
+									&cp);
+	}
+
+	hci_dev_unlock(hdev);
+}
+
 static inline void hci_le_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb)
 {
 	struct hci_ev_le_conn_complete *ev = (void *) skb->data;
@@ -2668,6 +2704,9 @@ void hci_event_packet(struct hci_dev *hdev, struct sk_buff *skb)
 
 	case HCI_EV_LE_META:
 		hci_le_meta_evt(hdev, skb);
+
+	case HCI_EV_REMOTE_OOB_DATA_REQUEST:
+		hci_remote_oob_data_request_evt(hdev, skb);
 		break;
 
 	default:
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index ba43b85..323b722 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -1310,6 +1310,74 @@ unlock:
 	return err;
 }
 
+static int add_remote_oob_data(struct sock *sk, u16 index, unsigned char *data,
+									u16 len)
+{
+	struct hci_dev *hdev;
+	struct mgmt_cp_add_remote_oob_data *cp = (void *) data;
+	int err;
+
+	BT_DBG("hci%u ", index);
+
+	if (len != sizeof(*cp))
+		return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
+									EINVAL);
+
+	hdev = hci_dev_get(index);
+	if (!hdev)
+		return cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA,
+									ENODEV);
+
+	hci_dev_lock_bh(hdev);
+
+	err = hci_add_remote_oob_data(hdev, &cp->bdaddr, cp->hash,
+								cp->randomizer);
+	if (err < 0)
+		err = cmd_status(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, -err);
+	else
+		err = cmd_complete(sk, index, MGMT_OP_ADD_REMOTE_OOB_DATA, NULL,
+									0);
+
+	hci_dev_unlock_bh(hdev);
+	hci_dev_put(hdev);
+
+	return err;
+}
+
+static int remove_remote_oob_data(struct sock *sk, u16 index,
+						unsigned char *data, u16 len)
+{
+	struct hci_dev *hdev;
+	struct mgmt_cp_remove_remote_oob_data *cp = (void *)data;
+	int err;
+
+	BT_DBG("hci%u ", index);
+
+	if (len != sizeof(*cp))
+		return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+									EINVAL);
+
+	hdev = hci_dev_get(index);
+	if (!hdev)
+		return cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+									ENODEV);
+
+	hci_dev_lock_bh(hdev);
+
+	err = hci_remove_remote_oob_data(hdev, &cp->bdaddr);
+	if (err < 0)
+		err = cmd_status(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+									-err);
+	else
+		err = cmd_complete(sk, index, MGMT_OP_REMOVE_REMOTE_OOB_DATA,
+								NULL, 0);
+
+	hci_dev_unlock_bh(hdev);
+	hci_dev_put(hdev);
+
+	return err;
+}
+
 int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 {
 	unsigned char *buf;
@@ -1408,6 +1476,13 @@ int mgmt_control(struct sock *sk, struct msghdr *msg, size_t msglen)
 	case MGMT_OP_READ_LOCAL_OOB_DATA:
 		err = read_local_oob_data(sk, index);
 		break;
+	case MGMT_OP_ADD_REMOTE_OOB_DATA:
+		err = add_remote_oob_data(sk, index, buf + sizeof(*hdr), len);
+		break;
+	case MGMT_OP_REMOVE_REMOTE_OOB_DATA:
+		err = remove_remote_oob_data(sk, index, buf + sizeof(*hdr),
+									len);
+		break;
 
 	default:
 		BT_DBG("Unknown op %u", opcode);
-- 
1.7.0.4


^ permalink raw reply related

* [PATCH] Bluetooth: Add counter for not acked HCI commands
From: Andrzej Kaczmarek @ 2011-03-01 18:16 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: par-gunnar.p.hjalmdahl, henrik.possung, Andrzej Kaczmarek

Adds counter for HCI commands which were sent but are not yet acked.
This is to prevent race conditions in scenarios where HCI commands
are sent between complete event and command status event, i.e.
last sent HCI command is not accounted in credits number returned
by command status event.

< HCI Command: Create Connection (0x01|0x0005) plen 13
    bdaddr 00:23:76:E3:24:58 ptype 0xcc18 rswitch 0x01 clkoffset 0x0000
    Packet type: DM1 DM3 DM5 DH1 DH3 DH5
> HCI Event: Command Status (0x0f) plen 4
    Create Connection (0x01|0x0005) status 0x00 ncmd 1
> HCI Event: Connect Complete (0x03) plen 11
    status 0x00 handle 1 bdaddr 00:23:76:E3:24:58 type ACL encrypt 0x00
< HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2
    handle 1
> HCI Event: Command Status (0x0f) plen 4
    Unknown (0x00|0x0000) status 0x00 ncmd 2
> HCI Event: Command Status (0x0f) plen 4
    Read Remote Supported Features (0x01|0x001b) status 0x00 ncmd 1
> HCI Event: Max Slots Change (0x1b) plen 3
    handle 1 slots 5
> HCI Event: Read Remote Supported Features (0x0b) plen 11
    status 0x00 handle 1
    Features: 0xbf 0xfe 0x8f 0xfe 0x9b 0xff 0x79 0x83
< HCI Command: Read Remote Extended Features (0x01|0x001c) plen 3
    handle 1 page 1
> HCI Event: Command Status (0x0f) plen 4
    Unknown (0x00|0x0000) status 0x00 ncmd 2
> HCI Event: Command Status (0x0f) plen 4
    Read Remote Extended Features (0x01|0x001c) status 0x00 ncmd 1
> HCI Event: Read Remote Extended Features (0x23) plen 13
    status 0x00 handle 1 page 1 max 1
    Features: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
< HCI Command: Authentication Requested (0x01|0x0011) plen 2
    handle 1
> HCI Event: Command Status (0x0f) plen 4
    Unknown (0x00|0x0000) status 0x00 ncmd 2
< HCI Command: Remote Name Request (0x01|0x0019) plen 10
    bdaddr 00:23:76:E3:24:58 mode 2 clkoffset 0x0000
> HCI Event: Command Status (0x0f) plen 4
    Authentication Requested (0x01|0x0011) status 0x00 ncmd 1
> HCI Event: Link Key Request (0x17) plen 6
    bdaddr 00:23:76:E3:24:58

Following command should not be sent here since we have effectively no
credits for HCI command, i.e. 1 credit returned by CS for Authentication
Requested was already consumed by Remote Name Request.

< HCI Command: Link Key Request Negative Reply (0x01|0x000c) plen 6
    bdaddr 00:23:76:E3:24:58
> HCI Event: Command Status (0x0f) plen 4
    Remote Name Request (0x01|0x0019) status 0x00 ncmd 0
> HCI Event: Command Complete (0x0e) plen 10
    Link Key Request Negative Reply (0x01|0x000c) ncmd 0
    status 0x0c bdaddr 00:23:76:E3:24:58
    Error: Command Disallowed

Signed-off-by: Andrzej Kaczmarek <andrzej.kaczmarek@tieto.com>
---
 include/net/bluetooth/hci_core.h |    1 +
 net/bluetooth/hci_core.c         |   10 ++++++++--
 net/bluetooth/hci_event.c        |    8 ++++++--
 3 files changed, 15 insertions(+), 4 deletions(-)

diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
index 441dadb..baf190b 100644
--- a/include/net/bluetooth/hci_core.h
+++ b/include/net/bluetooth/hci_core.h
@@ -121,6 +121,7 @@ struct hci_dev {
 	unsigned long	quirks;
 
 	atomic_t	cmd_cnt;
+	atomic_t	cmd_not_ack;
 	unsigned int	acl_cnt;
 	unsigned int	sco_cnt;
 	unsigned int	le_cnt;
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index b372fb8..1c6886d 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -531,6 +531,7 @@ int hci_dev_open(__u16 dev)
 
 	if (!test_bit(HCI_RAW, &hdev->flags)) {
 		atomic_set(&hdev->cmd_cnt, 1);
+		atomic_set(&hdev->cmd_not_ack, 0);
 		set_bit(HCI_INIT, &hdev->flags);
 		hdev->init_last_cmd = 0;
 
@@ -606,6 +607,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
 	/* Reset device */
 	skb_queue_purge(&hdev->cmd_q);
 	atomic_set(&hdev->cmd_cnt, 1);
+	atomic_set(&hdev->cmd_not_ack, 0);
 	if (!test_bit(HCI_RAW, &hdev->flags)) {
 		set_bit(HCI_INIT, &hdev->flags);
 		__hci_request(hdev, hci_reset_req, 0,
@@ -684,6 +686,7 @@ int hci_dev_reset(__u16 dev)
 		hdev->flush(hdev);
 
 	atomic_set(&hdev->cmd_cnt, 1);
+	atomic_set(&hdev->cmd_not_ack, 0);
 	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
 
 	if (!test_bit(HCI_RAW, &hdev->flags))
@@ -1074,6 +1077,7 @@ static void hci_cmd_timer(unsigned long arg)
 
 	BT_ERR("%s command tx timeout", hdev->name);
 	atomic_set(&hdev->cmd_cnt, 1);
+	atomic_add_unless(&hdev->cmd_not_ack, -1, 0);
 	tasklet_schedule(&hdev->cmd_task);
 }
 
@@ -2015,10 +2019,11 @@ static void hci_cmd_task(unsigned long arg)
 	struct hci_dev *hdev = (struct hci_dev *) arg;
 	struct sk_buff *skb;
 
-	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
+	BT_DBG("%s cnt %d not_ack %d", hdev->name, atomic_read(&hdev->cmd_cnt),
+					atomic_read(&hdev->cmd_not_ack));
 
 	/* Send queued commands */
-	if (atomic_read(&hdev->cmd_cnt)) {
+	if (atomic_read(&hdev->cmd_cnt) > atomic_read(&hdev->cmd_not_ack)) {
 		skb = skb_dequeue(&hdev->cmd_q);
 		if (!skb)
 			return;
@@ -2028,6 +2033,7 @@ static void hci_cmd_task(unsigned long arg)
 		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
 		if (hdev->sent_cmd) {
 			atomic_dec(&hdev->cmd_cnt);
+			atomic_inc(&hdev->cmd_not_ack);
 			hci_send_frame(skb);
 			mod_timer(&hdev->cmd_timer,
 				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 3fbfa50..3cf63a1 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1766,8 +1766,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
 		break;
 	}
 
-	if (ev->opcode != HCI_OP_NOP)
+	if (ev->opcode != HCI_OP_NOP) {
 		del_timer(&hdev->cmd_timer);
+		atomic_add_unless(&hdev->cmd_not_ack, -1, 0);
+	}
 
 	if (ev->ncmd) {
 		atomic_set(&hdev->cmd_cnt, 1);
@@ -1844,8 +1846,10 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
 		break;
 	}
 
-	if (ev->opcode != HCI_OP_NOP)
+	if (ev->opcode != HCI_OP_NOP) {
 		del_timer(&hdev->cmd_timer);
+		atomic_add_unless(&hdev->cmd_not_ack, -1, 0);
+	}
 
 	if (ev->ncmd) {
 		atomic_set(&hdev->cmd_cnt, 1);
-- 
1.7.0.4

Patch on behalf of ST-Ericsson

^ permalink raw reply related

* headset answer button with HFP and telephony-dummy
From: Peter Kornatowski @ 2011-03-01 18:26 UTC (permalink / raw)
  To: linux-bluetooth

Hello,

I want to catch the answer button signal of a bluetooth headset when 
connected in HFP mode (HSP is trivial through the dbus-headset-signal 
"AnswerRequested"). I don't want to use the computer as the "headset 
part", but as the "audio gateway part". I have a small self-build app 
that can handle VoIP-calls and Bluetooth-audio through bluez and 
pulseaudio. Now I want the app to recognize the answer button being 
pressed and then answer or hang up a call. I know that it has to be 
done through a telephony-dummy because of the more complicated HFP 
state machine. So I also digged into the source of the corresponding 
.c files and searched the web. But I still have several questions left:
1. The bluez bindings for ofono and maemo seem to be just fulfilling 
the "headset part", so when connecting a mobile phone to the computer 
through Bluetooth. But I need the other direction. Is this possible 
with ofono or maemo?
2. I found this patch on the web: 
http://whitequark.livejournal.com/20590.html. It is already 
integrated into bluez (since version 4.6x), so my problem seems to be 
possible to solve with the telephony-dummy. But I tested it and when 
the headset is in connected mode, I don't receive anything when 
pressing the answer button. In playing mode I just received "AT+BLDN" 
(last_dialed_number) and "AT+CHUP" (terminate_call). But according to 
the patch I should receive "AT+BVRA" (voice_dial). Should the headset 
be in some state (if yes, in which one and how do I trigger it)?
3. Should I be able to use the dbus-methods in the telephony-dummy to 
simulate a "HFP state machine" and maybe be able to catch the answer 
button then? But here only the "audio gateway role" on the remote 
device (org.bluez.HeadsetGateway) is documented in the audio-api.txt, 
not the other direction.

Thanks,
Peter Kornatowski 


^ permalink raw reply

* Re: [PATCH 1/2] Move pcsuite drivers to its own plugin
From: Johan Hedberg @ 2011-03-01 18:45 UTC (permalink / raw)
  To: luiz.dentz; +Cc: linux-bluetooth, Luiz Augusto von Dentz
In-Reply-To: <1298749782-24129-3-git-send-email-luiz.dentz@gmail.com>

Hi Luiz,

On Sat, Feb 26, 2011, luiz.dentz@gmail.com wrote:
> This make it easier to enable/disable this funcionality as a whole.
> ---
>  Makefile.am            |    6 +-
>  configure.ac           |    9 +-
>  plugins/ftp.c          |  165 +---------------
>  plugins/ftp.h          |   30 +++
>  plugins/nokia-backup.c |  309 -----------------------------
>  plugins/pcsuite.c      |  515 ++++++++++++++++++++++++++++++++++++++++++++++++
>  6 files changed, 561 insertions(+), 473 deletions(-)
>  create mode 100644 plugins/ftp.h
>  delete mode 100644 plugins/nokia-backup.c
>  create mode 100644 plugins/pcsuite.c

Thanks. Both patches have been pushed upstream (with a couple of fixes
to the commit messages).

Johan

^ permalink raw reply

* Re: [PATCH v1] Fix HCI LE advertising report dump
From: Johan Hedberg @ 2011-03-01 18:59 UTC (permalink / raw)
  To: Andre Dieb Martins; +Cc: linux-bluetooth
In-Reply-To: <1298865502-12676-1-git-send-email-andre.dieb@signove.com>

Hi André,

On Mon, Feb 28, 2011, Andre Dieb Martins wrote:
> LE advertising report event has only one data block for each report.
> Thus, we can't reuse ext_inquiry_response_dump(), which loops over
> successive data blocks until reaches a zero-length one.
> 
> This commit introduces ext_inquiry_data_dump(), which dumps a frame
> containing data formatted according to [Vol 3] Part C, Section 8. This
> function is reused by ext_inquiry_response_dump().
> 
> Also adds RSSI parsing to each advertising report.
> ---
>  parser/hci.c |  146 +++++++++++++++++++++++++++++++++------------------------
>  1 files changed, 84 insertions(+), 62 deletions(-)

Pushed upstream. Thanks. I had to fix your commit message first though.
Please make sure that the lines are short enough to be properly viewable
with git log on a 80-column wide terminal (git log indents them by 4
characters).

Johan

^ permalink raw reply

* Re: [PATCH] Adjust prefix of contact id for pulling single vCard
From: Johan Hedberg @ 2011-03-01 19:02 UTC (permalink / raw)
  To: Rafal Michalski; +Cc: linux-bluetooth
In-Reply-To: <1298894632-30497-1-git-send-email-michalski.raf@gmail.com>

Hi Rafal,

On Mon, Feb 28, 2011, Rafal Michalski wrote:
> Pulling single vCard is related to recognizing it by prefix of contact
> id. Previously it was "contact: " and has been changed to "urn:uuid:".
> This patch fixes it and allows to pull valid single vCard.
> ---
>  plugins/phonebook-tracker.c |    2 +-
>  1 files changed, 1 insertions(+), 1 deletions(-)

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 1/4] TODO: Remove item related to ATT transation timeouts
From: Johan Hedberg @ 2011-03-01 19:12 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1298900653-7567-1-git-send-email-claudio.takahasi@openbossa.org>

Hi Claudio,

On Mon, Feb 28, 2011, Claudio Takahasi wrote:
> ---
>  TODO |    7 -------
>  1 files changed, 0 insertions(+), 7 deletions(-)

All four patches have been pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] Fix pulling phonebook entries without last name
From: Johan Hedberg @ 2011-03-01 19:13 UTC (permalink / raw)
  To: Lukasz Pawlik; +Cc: linux-bluetooth
In-Reply-To: <1298906383-14521-1-git-send-email-lucas.pawlik@gmail.com>

Hi Lukasz,

On Mon, Feb 28, 2011, Lukasz Pawlik wrote:
> This patch fix problem with pulling phonebook entries using PBAP without
> last name filled. Previously last name was used to sort phonebook data
> now only tracker id is used.
> ---
>  plugins/phonebook-tracker.c |    5 ++---
>  1 files changed, 2 insertions(+), 3 deletions(-)

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH 1/5] hcitool: Add command to add a device to LE White List
From: Johan Hedberg @ 2011-03-01 19:19 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth, Arun Kumar Singh
In-Reply-To: <1298917134-8229-1-git-send-email-claudio.takahasi@openbossa.org>

Hi Claudio,

On Mon, Feb 28, 2011, Claudio Takahasi wrote:
> From: Arun Kumar Singh <arunkat@gmail.com>
> 
> ---
>  lib/hci.c       |   29 +++++++++++++++++++++++++++++
>  lib/hci.h       |    6 ++++++
>  lib/hci_lib.h   |    2 +-
>  tools/hcitool.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
>  4 files changed, 83 insertions(+), 1 deletions(-)

All five patches have been pushed upstream. Thanks for sorting them out
and resending.

Johan

^ permalink raw reply

* Re: [PATCH] TODO: Fix GATT over BR/EDR
From: Johan Hedberg @ 2011-03-01 19:20 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth
In-Reply-To: <1298986099-4720-1-git-send-email-claudio.takahasi@openbossa.org>

Hi Claudio,

On Tue, Mar 01, 2011, Claudio Takahasi wrote:
> ---
> 
>  Needs to be applied after: "[PATCH 4/4] TODO: Add item to implement device
>  type in the DeviceFound signal"
> 
>  TODO |    9 ++++++---
>  1 files changed, 6 insertions(+), 3 deletions(-)

Pushed upstream. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH] Bluetooth: Add counter for not acked HCI commands
From: Brian Gix @ 2011-03-01 19:25 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung
In-Reply-To: <1299003369-17901-1-git-send-email-andrzej.kaczmarek@tieto.com>

Hi Andrzej,

On 11-03-01 10:16 AM, Andrzej Kaczmarek wrote:
> Adds counter for HCI commands which were sent but are not yet acked.
> This is to prevent race conditions in scenarios where HCI commands
> are sent between complete event and command status event, i.e.
> last sent HCI command is not accounted in credits number returned
> by command status event.
>
> <  HCI Command: Create Connection (0x01|0x0005) plen 13
>      bdaddr 00:23:76:E3:24:58 ptype 0xcc18 rswitch 0x01 clkoffset 0x0000
>      Packet type: DM1 DM3 DM5 DH1 DH3 DH5
>> HCI Event: Command Status (0x0f) plen 4
>      Create Connection (0x01|0x0005) status 0x00 ncmd 1
>> HCI Event: Connect Complete (0x03) plen 11
>      status 0x00 handle 1 bdaddr 00:23:76:E3:24:58 type ACL encrypt 0x00
> <  HCI Command: Read Remote Supported Features (0x01|0x001b) plen 2
>      handle 1
>> HCI Event: Command Status (0x0f) plen 4
>      Unknown (0x00|0x0000) status 0x00 ncmd 2
>> HCI Event: Command Status (0x0f) plen 4
>      Read Remote Supported Features (0x01|0x001b) status 0x00 ncmd 1
>> HCI Event: Max Slots Change (0x1b) plen 3
>      handle 1 slots 5
>> HCI Event: Read Remote Supported Features (0x0b) plen 11
>      status 0x00 handle 1
>      Features: 0xbf 0xfe 0x8f 0xfe 0x9b 0xff 0x79 0x83
> <  HCI Command: Read Remote Extended Features (0x01|0x001c) plen 3
>      handle 1 page 1
>> HCI Event: Command Status (0x0f) plen 4
>      Unknown (0x00|0x0000) status 0x00 ncmd 2
>> HCI Event: Command Status (0x0f) plen 4
>      Read Remote Extended Features (0x01|0x001c) status 0x00 ncmd 1
>> HCI Event: Read Remote Extended Features (0x23) plen 13
>      status 0x00 handle 1 page 1 max 1
>      Features: 0x01 0x00 0x00 0x00 0x00 0x00 0x00 0x00
> <  HCI Command: Authentication Requested (0x01|0x0011) plen 2
>      handle 1
>> HCI Event: Command Status (0x0f) plen 4
>      Unknown (0x00|0x0000) status 0x00 ncmd 2
> <  HCI Command: Remote Name Request (0x01|0x0019) plen 10
>      bdaddr 00:23:76:E3:24:58 mode 2 clkoffset 0x0000
>> HCI Event: Command Status (0x0f) plen 4
>      Authentication Requested (0x01|0x0011) status 0x00 ncmd 1
>> HCI Event: Link Key Request (0x17) plen 6
>      bdaddr 00:23:76:E3:24:58
>
> Following command should not be sent here since we have effectively no
> credits for HCI command, i.e. 1 credit returned by CS for Authentication
> Requested was already consumed by Remote Name Request.
>
> <  HCI Command: Link Key Request Negative Reply (0x01|0x000c) plen 6
>      bdaddr 00:23:76:E3:24:58
>> HCI Event: Command Status (0x0f) plen 4
>      Remote Name Request (0x01|0x0019) status 0x00 ncmd 0
>> HCI Event: Command Complete (0x0e) plen 10
>      Link Key Request Negative Reply (0x01|0x000c) ncmd 0
>      status 0x0c bdaddr 00:23:76:E3:24:58
>      Error: Command Disallowed
>
> Signed-off-by: Andrzej Kaczmarek<andrzej.kaczmarek@tieto.com>
> ---
>   include/net/bluetooth/hci_core.h |    1 +
>   net/bluetooth/hci_core.c         |   10 ++++++++--
>   net/bluetooth/hci_event.c        |    8 ++++++--
>   3 files changed, 15 insertions(+), 4 deletions(-)
>
> diff --git a/include/net/bluetooth/hci_core.h b/include/net/bluetooth/hci_core.h
> index 441dadb..baf190b 100644
> --- a/include/net/bluetooth/hci_core.h
> +++ b/include/net/bluetooth/hci_core.h
> @@ -121,6 +121,7 @@ struct hci_dev {
>   	unsigned long	quirks;
>
>   	atomic_t	cmd_cnt;
> +	atomic_t	cmd_not_ack;
>   	unsigned int	acl_cnt;
>   	unsigned int	sco_cnt;
>   	unsigned int	le_cnt;
> diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
> index b372fb8..1c6886d 100644
> --- a/net/bluetooth/hci_core.c
> +++ b/net/bluetooth/hci_core.c
> @@ -531,6 +531,7 @@ int hci_dev_open(__u16 dev)
>
>   	if (!test_bit(HCI_RAW,&hdev->flags)) {
>   		atomic_set(&hdev->cmd_cnt, 1);
> +		atomic_set(&hdev->cmd_not_ack, 0);
>   		set_bit(HCI_INIT,&hdev->flags);
>   		hdev->init_last_cmd = 0;
>
> @@ -606,6 +607,7 @@ static int hci_dev_do_close(struct hci_dev *hdev)
>   	/* Reset device */
>   	skb_queue_purge(&hdev->cmd_q);
>   	atomic_set(&hdev->cmd_cnt, 1);
> +	atomic_set(&hdev->cmd_not_ack, 0);
>   	if (!test_bit(HCI_RAW,&hdev->flags)) {
>   		set_bit(HCI_INIT,&hdev->flags);
>   		__hci_request(hdev, hci_reset_req, 0,
> @@ -684,6 +686,7 @@ int hci_dev_reset(__u16 dev)
>   		hdev->flush(hdev);
>
>   	atomic_set(&hdev->cmd_cnt, 1);
> +	atomic_set(&hdev->cmd_not_ack, 0);
>   	hdev->acl_cnt = 0; hdev->sco_cnt = 0; hdev->le_cnt = 0;
>
>   	if (!test_bit(HCI_RAW,&hdev->flags))
> @@ -1074,6 +1077,7 @@ static void hci_cmd_timer(unsigned long arg)
>
>   	BT_ERR("%s command tx timeout", hdev->name);
>   	atomic_set(&hdev->cmd_cnt, 1);
> +	atomic_add_unless(&hdev->cmd_not_ack, -1, 0);
>   	tasklet_schedule(&hdev->cmd_task);
>   }
>
> @@ -2015,10 +2019,11 @@ static void hci_cmd_task(unsigned long arg)
>   	struct hci_dev *hdev = (struct hci_dev *) arg;
>   	struct sk_buff *skb;
>
> -	BT_DBG("%s cmd %d", hdev->name, atomic_read(&hdev->cmd_cnt));
> +	BT_DBG("%s cnt %d not_ack %d", hdev->name, atomic_read(&hdev->cmd_cnt),
> +					atomic_read(&hdev->cmd_not_ack));
>
>   	/* Send queued commands */
> -	if (atomic_read(&hdev->cmd_cnt)) {
> +	if (atomic_read(&hdev->cmd_cnt)>  atomic_read(&hdev->cmd_not_ack)) {

See below for fuller explanation of my opinion.

But I would make this test be-->   cmd_cnt && !cmd_not_acked

>   		skb = skb_dequeue(&hdev->cmd_q);
>   		if (!skb)
>   			return;
> @@ -2028,6 +2033,7 @@ static void hci_cmd_task(unsigned long arg)
>   		hdev->sent_cmd = skb_clone(skb, GFP_ATOMIC);
>   		if (hdev->sent_cmd) {
>   			atomic_dec(&hdev->cmd_cnt);
> +			atomic_inc(&hdev->cmd_not_ack);
>   			hci_send_frame(skb);
>   			mod_timer(&hdev->cmd_timer,
>   				  jiffies + msecs_to_jiffies(HCI_CMD_TIMEOUT));
> diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
> index 3fbfa50..3cf63a1 100644
> --- a/net/bluetooth/hci_event.c
> +++ b/net/bluetooth/hci_event.c
> @@ -1766,8 +1766,10 @@ static inline void hci_cmd_complete_evt(struct hci_dev *hdev, struct sk_buff *sk
>   		break;
>   	}
>
> -	if (ev->opcode != HCI_OP_NOP)
> +	if (ev->opcode != HCI_OP_NOP) {
>   		del_timer(&hdev->cmd_timer);
> +		atomic_add_unless(&hdev->cmd_not_ack, -1, 0);
> +	}
>
>   	if (ev->ncmd) {
>   		atomic_set(&hdev->cmd_cnt, 1);
> @@ -1844,8 +1846,10 @@ static inline void hci_cmd_status_evt(struct hci_dev *hdev, struct sk_buff *skb)
>   		break;
>   	}
>
> -	if (ev->opcode != HCI_OP_NOP)
> +	if (ev->opcode != HCI_OP_NOP) {
>   		del_timer(&hdev->cmd_timer);
> +		atomic_add_unless(&hdev->cmd_not_ack, -1, 0);
> +	}
>
>   	if (ev->ncmd) {
>   		atomic_set(&hdev->cmd_cnt, 1);


The problem you describe sounds like one I had to solve in the past, but 
unfortunately, I think it may be a little more difficult to solve here. 
  This particular baseband appears to have an outstanding Cmd queue of 
2.  It also appears to consume one of them for extended periods of time 
when making requests of the remote device, and using the NOP 
Cmd-Status-Event to inform the host that the slot is now free.

As you are observing, the completion of the task (triggering additional 
requests locally) overlaps with these NOP responses, giving a false 
count to the host of available cmd slots.

Personally, I consider this to be a baseband bug, which could have been 
avoided by having a max outstanding queue of 1.

Note 1:
My biggest problem with your patch is the point marked above.  I agree 
that it would solve the problem you observed, and your overall analysis 
of the situation, but because of the way this particular baseband is 
operating, and the way I have seen other basebands operate in the past, 
I think this decision point as to when to send the next command is 
incorrect.

A flaw in the HCI command handshaking paradigm is that a baseband can 
decide to take away or not take away one of these slots, and give you 
notification asynchronously. I have seen basebands with presumptively 
two slots return a cmd status with ncmd 0 when getting a remote device 
name, if no ACL connection was currently established, for example.

The safest way I have seen this problem handled is to force a 
psuedo-single-threading of commands on the system by NEVER sending a 
command while another command has not yet received it's Cmd-Status or 
Cmd-Cmplt event. In other words, instead of the test for cmd_cnt > 
cmd_not_acked, I would simply make into cmd_cnt && !cmd_not_acked.

I think the rest of it is basically OK.

Note that it is still then possible to have multiple "very-asynchronous" 
commands that include remote interaction, but it ensures that that part 
that is suppose to be functionally syncrounous (Cmd + Status || Cmplt) 
is done the way most basebands are expecting them to be. I believe this 
to be the intended usage mode of the HCI paradigm.




-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply

* Re: [PATCH] Bluetooth: Add counter for not acked HCI commands
From: Brian Gix @ 2011-03-01 19:29 UTC (permalink / raw)
  To: Andrzej Kaczmarek; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung
In-Reply-To: <1299003369-17901-1-git-send-email-andrzej.kaczmarek@tieto.com>

Hi Again,

On 11-03-01 10:16 AM, Andrzej Kaczmarek wrote:
[...]

>   			atomic_dec(&hdev->cmd_cnt);
> +			atomic_inc(&hdev->cmd_not_ack);
[...]

Also, I am not sure this means what you may intend it to mean. I think 
that this is intended to do both of these operations "together 
atomically", but that as written, it is possible for an interruption to 
occur between the two operations.


-- 
Brian Gix
bgix@codeaurora.org
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum

^ permalink raw reply

* Re: [PATCH] Bluetooth: Fix some small code style issues in mgmt.c
From: Gustavo F. Padovan @ 2011-03-02  1:23 UTC (permalink / raw)
  To: Szymon Janc; +Cc: linux-bluetooth, par-gunnar.p.hjalmdahl, henrik.possung
In-Reply-To: <1298994934-23281-3-git-send-email-szymon.janc@tieto.com>

Hi Szymon,

* Szymon Janc <szymon.janc@tieto.com> [2011-03-01 16:55:34 +0100]:

> Signed-off-by: Szymon Janc <szymon.janc@tieto.com>
> ---
>  net/bluetooth/mgmt.c |   14 +++++---------
>  1 files changed, 5 insertions(+), 9 deletions(-)

The 3 patches were applied, thanks.

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH] work around for l2cap NULL dereference in l2cap_conn_start
From: Andrei Warkentin @ 2011-03-02  1:31 UTC (permalink / raw)
  To: David Fries; +Cc: Gustavo F. Padovan, linux-bluetooth, linux-kernel
In-Reply-To: <20110221043601.GB22204@spacedout.fries.net>

Hi all,

I don't have an S305 headset at the moment to play with this, but, our
tree (2.6.36) has
a fix like this for this issue.


 				if (bt_sk(sk)->defer_setup) {
 					struct sock *parent = bt_sk(sk)->parent;
 					rsp.result = cpu_to_le16(L2CAP_CR_PEND);
 					rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
-					parent->sk_data_ready(parent, 0);
+					if (parent)
+						parent->sk_data_ready(parent, 0);

 				} else {
 					sk->sk_state = BT_CONFIG;
 					rsp.result = cpu_to_le16(L2CAP_CR_SUCCESS);

The comment is:

    Bluetooth: Hack: Don't dereference null pointer.

    This avoids the S305 panic during incoming connection.

    S305 sends PSM 25 L2CAP connection request before the L2CAP info response.
    When we receive that info response we crash on null pointer here.

Sorry for the wait,
A

On Sun, Feb 20, 2011 at 10:36 PM, David Fries <david@fries.net> wrote:
> bt_sk(sk)->parent can be NULL in l2cap_conn_start in state BT_CONNECT2
> at least when a headset device pairs and the play button was pressed
> right before pairing.
>
> Signed-off-by: David Fries <david@fries.net>
> ---
> I removed the printk, can this be merged to the bluetooth next tree?
>
> On Mon, Feb 14, 2011 at 03:40:46PM -0600, Andrei Warkentin wrote:
>> FWIW still need it in 2.6.36.
>
> Andrei, I'm curious, what's your hardware hardware and bluetooth
> device that's trigginer the crash?
>
>> On Mon, Feb 14, 2011 at 8:56 AM, Gustavo F. Padovan
>> <padovan@profusion.mobi> wrote:
>> > Hi David,
>> >
>> > * David Fries <david@fries.net> [2011-02-10 21:53:09 -0600]:
>> >
>> >> Here's a patch to avoid a very repeatable crash in the N900.  If I
>> >> take a Motorola S305 bluetooth headset that was previously paried with
>> >> the N900, turn it on, and press the play button before the headphones
>> >> automatically pair with the cell phone, the N900 will crash (and
>> >> reboot) in pairing.  If I wait until after they have paired there
>> >> isn't any problem.  The patch is against the kernel-power
>> >> 2.6.28-maemo46 by Thomas Tanner, the stock Nokia PR1.2 oops looked
>> >> the same, I just haven't gone back to that kernel.
>> >
>> > This is a very old kernel. You need to check this issue against
>> > bluetooth-next-2.6.
>
>  net/bluetooth/l2cap.c |    3 ++-
>  1 files changed, 2 insertions(+), 1 deletions(-)
>
> diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
> index ed83c1f..a7aa4d9 100644
> --- a/net/bluetooth/l2cap.c
> +++ b/net/bluetooth/l2cap.c
> @@ -408,7 +408,8 @@ static void l2cap_conn_start(struct l2cap_conn *conn)
>                                        struct sock *parent = bt_sk(sk)->parent;
>                                        rsp.result = cpu_to_le16(L2CAP_CR_PEND);
>                                        rsp.status = cpu_to_le16(L2CAP_CS_AUTHOR_PEND);
> -                                       parent->sk_data_ready(parent, 0);
> +                                       if(parent)
> +                                               parent->sk_data_ready(parent,0);
>
>                                } else {
>                                        sk->sk_state = BT_CONFIG;
> --
> 1.7.2.3
>
>

^ permalink raw reply

* pull request: bluetooth-next-2.6 2011-03-01
From: Gustavo F. Padovan @ 2011-03-02  3:47 UTC (permalink / raw)
  To: linville; +Cc: linux-wireless, linux-bluetooth

Hi John,

Here is the latest batch of Bluetooth changes, they are most changes in the
HCI Management interface both from Johan Hedberg and Szymon Janc. The rest are
just clean ups and bug fixes.

Please pull, thanks a lot!

The following changes since commit e46395a4b3d32d161d8b6d8e4a002972b1faae3e:

  mac80211: make rate control Kconfig warning depend on mac80211 (2011-03-01 13:48:22 -0500)

are available in the git repository at:
  git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-next-2.6.git master

Anand Gadiyar (2):
      Bluetooth: fix build break on hci_sock.c
      Bluetooth: remove unnecessary call to hci_sock_cleanup

Anderson Briglia (1):
      Bluetooth: Fix LE conn creation

Gustavo F. Padovan (1):
      Bluetooth: Remove duplicated BT_INFO() from L2CAP

Johan Hedberg (8):
      Bluetooth: Make pending_add return a pointer to the added entry
      Bluetooth: Add mgmt_pair_device command
      Bluetooth: Add management support for user confirmation request
      Bluetooth: Fix mgmt_pin_code_reply command status opcode
      Bluetooth: Fix mgmt_pin_code_reply return parameters
      Bluetooth: Add mgmt_auth_failed event
      Bluetooth: Fix inititial value for remote authentication requirements
      Bluetooth: Fix unnecessary list traversal in mgmt_pending_remove

Szymon Janc (8):
      Bluetooth: Use proper command structure in remove_uuid
      Bluetooth: Move index to common header in management interface
      Bluetooth: Validate data size before accessing mgmt commands
      Bluetooth: Fix possible NULL pointer dereference in cmd_complete                         
      Bluetooth: Log all parameters in cmd_status for easier debugging                         
      Bluetooth: Remove unused code from get_connections                                       
      Bluetooth: Use variable name instead of type in sizeof()                                 
      Bluetooth: Fix some small code style issues in mgmt.c                                    
                                                                                               
Ville Tervo (1):                                                                               
      Bluetooth: Use ERR_PTR as return error from hci_connect                                  
                                                                                               
 include/net/bluetooth/hci.h      |   17 +                                                     
 include/net/bluetooth/hci_core.h |   21 +                                                     
 include/net/bluetooth/mgmt.h     |   73 ++--                                                  
 net/bluetooth/af_bluetooth.c     |    4 +-                                                    
 net/bluetooth/hci_conn.c         |    8 +-                                                    
 net/bluetooth/hci_event.c        |   69 ++++-                                                 
 net/bluetooth/hci_sock.c         |    2 +-                                                    
 net/bluetooth/l2cap_core.c       |   13 +-                                                    
 net/bluetooth/mgmt.c             |  751 +++++++++++++++++++++++++-------------                
 net/bluetooth/sco.c              |    7 +-                                                    
 10 files changed, 663 insertions(+), 302 deletions(-)                                        

-- 
Gustavo F. Padovan
http://profusion.mobi

^ permalink raw reply

* Re: [PATCH] work around for l2cap NULL dereference in l2cap_conn_start
From: David Fries @ 2011-03-02  6:19 UTC (permalink / raw)
  To: Liang Bao, Andrei Warkentin, linux-bluetooth, linux-kernel,
	Feng Tang
In-Reply-To: <20110228173022.GC2165@joana>

On Mon, Feb 28, 2011 at 02:30:22PM -0300, Gustavo F. Padovan wrote:
> Hi David,
> 
> * David Fries <david@fries.net> [2011-02-27 23:03:40 -0600]:
> 
> > On Sun, Feb 27, 2011 at 04:15:45PM -0300, Gustavo F. Padovan wrote:
> > > I pushed the following patch to bluetooth-2.6 tree. It should fix the problem
> > > by avoiding connections to be accepted before a L2CAP info response comes:
> > 
> > Is
> > git://git.kernel.org/pub/scm/linux/kernel/git/padovan/bluetooth-2.6.git
> > the bluetooth-2.6 tree you mentioned?  I don't see your patch there.
> > As a side note, the inline patch in your e-mail has the tabs replaced by
> > spaces, once I changed them, it applied cleanly.
> > 
> > I first reverted to the base N900 kernel-power-2.6.28 46 (none of my
> > changes or debugging), it crashed as expected.  I then applied your
> > patch 743400e0, and it still crashed.  I added back the
> > l2cap_conn_start parent check and some debugging in af_bluetooth.c
> > dmesg debug output and patches follow.
> 
> I want to see a test with this patch and a recent kernel. We added many fixes
> to stack in the last two years. Can you test this scenario?

I'm sorry, but apparently not, at least this post says 2.6.37 isn't
going to happen for the N900 and Maemo.
http://forums.internettablettalk.com/showthread.php?t=70082

I tried 2.6.37-n900 from
git://gitorious.org/nokia-n900-kernel/nokia-n900-kernel.git anyway,
but the display visibly degrades like it isn't being updated and
doesn't apparently get any further.  I don't have anyway to debug it
further.

-- 
David Fries <david@fries.net>
http://fries.net/~david/ (PGP encryption key available)

^ permalink raw reply

* bluez crash when setting with-telephony = ofono
From: Zheng, Wu @ 2011-03-02  7:08 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org

Hi:

I compiled the program of bluez.

./configure --disable-static --enable-cups --enable-hid2hci --enable-dfutool --enable-bccmd --enable-hidd --enable-pand --enable-dund -gstreamer -enable-alsa -enable-usb -enable-tools --enable-test -with-telephony=ofono.

However, after I run bluetoothd -d -n,  the bluez crash.

it crash at g_slist_foreach(watches, (GFunc) remove_watch, NULL) in the function of telephony_exit();

When removing the items of watches, bluez crash.

The log show that it crash when removing the last item of watches.

The error is "Process 1228:Attempt to remove filter function 0xb76dda60 user data(nul), but no such filter has been added ..."

Why bluez crash?

Best regards
Zheng wu

^ permalink raw reply

* Re: Do you have a plan to split ERTM into a separate file?
From: Marcel Holtmann @ 2011-03-02  7:26 UTC (permalink / raw)
  To: Gustavo F. Padovan
  Cc: Haijun Liu, (linux-bluetooth@vger.kernel.org), Dan Tian
In-Reply-To: <20110228171941.GA2165@joana>

Hi Gustavo,

> > Do you have a plan to split ERTM code into a separate file?
> > It may be easier to read/learn ERTM mechanism with loosely coupled code for people.
> > Thank you! :)
> 
> I don't. But I'll be happy if you send me patches for that. ;)

this is actually a bad idea. So lets not even go there.

Regards

Marcel



^ permalink raw reply

* [PATCH 0/1 v3] Fix response on adapter RequestSession method
From: Dmitriy Paliy @ 2011-03-02  8:24 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz, anderson.lizardo

Hi,

This is modified version of submission with version 2. Here comments
of Anderson Lizardo are taken into account. Thanks to him for thorough
review.

BR,
Dmitriy


^ permalink raw reply

* [PATCH v3] Fix response on adapter RequestSession method
From: Dmitriy Paliy @ 2011-03-02  8:24 UTC (permalink / raw)
  To: linux-bluetooth, luiz.dentz, anderson.lizardo; +Cc: Dmitriy Paliy
In-Reply-To: <1299054257-15806-1-git-send-email-dmitriy.paliy@nokia.com>

Fixes response on adapter RequestSession method to be sent after mode is
changed, if such is necessary. More specifically, change of power off mode
to power on is in question.

Currenty response is sent when mode change is confirmed by agent, not by
response from controller. Such may lead to failed CreateDevice method if
it is called quickly enough after RequestSession when controller is in
powered off state.

New session is not created if there is already a session for such D-Bus
message.
---
 src/adapter.c |   52 +++++++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 41 insertions(+), 11 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 2e11832..b119fd1 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -452,6 +452,20 @@ static int adapter_set_mode(struct btd_adapter *adapter, uint8_t mode)
 	return 0;
 }
 
+static struct session_req *find_session_by_msg(GSList *list, const DBusMessage *msg)
+{
+	GSList *l;
+
+	for (l = list; l; l = l->next) {
+		struct session_req *req = l->data;
+
+		if (req->msg == msg)
+			return req;
+	}
+
+	return NULL;
+}
+
 static int set_mode(struct btd_adapter *adapter, uint8_t new_mode,
 			DBusMessage *msg)
 {
@@ -496,11 +510,18 @@ done:
 
 	DBG("%s", modestr);
 
-	if (msg != NULL)
-		/* Wait for mode change to reply */
-		adapter->pending_mode = create_session(adapter, connection,
-							msg, new_mode, NULL);
-	else
+	if (msg != NULL) {
+		struct session_req *req;
+
+		req = find_session_by_msg(adapter->mode_sessions, msg);
+		if (req) {
+			adapter->pending_mode = req;
+			session_ref(req);
+		} else
+			/* Wait for mode change to reply */
+			adapter->pending_mode = create_session(adapter,
+					connection, msg, new_mode, NULL);
+	} else
 		/* Nothing to reply just write the new mode */
 		adapter->mode = new_mode;
 
@@ -795,16 +816,25 @@ static void confirm_mode_cb(struct agent *agent, DBusError *derr, void *data)
 		return;
 	}
 
-	err = set_mode(req->adapter, req->mode, NULL);
+	err = set_mode(req->adapter, req->mode, req->msg);
 	if (err < 0)
 		reply = btd_error_failed(req->msg, strerror(-err));
-	else
+	else if (!req->adapter->pending_mode)
 		reply = dbus_message_new_method_return(req->msg);
+	else
+		reply = NULL;
 
-	g_dbus_send_message(req->conn, reply);
+	if (reply) {
+		/*
+		 * Send reply immediately only if there was an error changing
+		 * mode, or change is not needed. Otherwise, reply is sent in
+		 * set_mode_complete.
+		 */
+		g_dbus_send_message(req->conn, reply);
 
-	dbus_message_unref(req->msg);
-	req->msg = NULL;
+		dbus_message_unref(req->msg);
+		req->msg = NULL;
+	}
 
 	if (!find_session(req->adapter->mode_sessions, req->owner))
 		session_unref(req);
-- 
1.7.1


^ permalink raw reply related

* [PATCH 0/4] Message Access Profile plugin
From: lkslawek @ 2011-03-02  9:36 UTC (permalink / raw)
  To: linux-bluetooth

These are the first ones of upcoming series of patches implementing Message
Access Profile (server role) in obexd. 

The work is more than less complete (~4k lines now), but as advised by Johan,
I'm cutting the whole thing into smaller pieces before sending this here.

Regards,
Slawomir Bochenski

 .gitignore               |    1 +
 Makefile.am              |   10 ++-
 configure.ac             |   12 ++
 plugins/mas.c            |  338 ++++++++++++++++++++++++++++++++++++++++++++++
 plugins/messages-dummy.c |   28 ++++
 plugins/messages.h       |   37 +++++
 src/main.c               |   11 ++-
 src/obex.h               |    1 +
 8 files changed, 435 insertions(+), 3 deletions(-)

^ permalink raw reply

* [PATCH 1/4] Add skeleton for Message Access Profile plugin
From: lkslawek @ 2011-03-02  9:36 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Slawomir Bochenski
In-Reply-To: <1299058614-8904-1-git-send-email-lkslawek@gmail.com>

From: Slawomir Bochenski <lkslawek@gmail.com>

This patch introduces skeleton of a plugin supporting server role side
of Bluetooth SIG profile defining procedures for exchanging message
objects.

The plugin can be compiled with different backends used for accessing
message repository. This can be selected during configure:

	./configure --with-messages=backend_name

When no backend is specified, the default dummy is chosen.

There is also a new command line option to obexd needed to start Message
Access service:

	obexd [...] --mas
---
 .gitignore               |    1 +
 Makefile.am              |   10 +++++++++-
 configure.ac             |   12 ++++++++++++
 plugins/mas.c            |   42 ++++++++++++++++++++++++++++++++++++++++++
 plugins/messages-dummy.c |   28 ++++++++++++++++++++++++++++
 plugins/messages.h       |   22 ++++++++++++++++++++++
 src/main.c               |   11 +++++++++--
 src/obex.h               |    1 +
 8 files changed, 124 insertions(+), 3 deletions(-)
 create mode 100644 plugins/mas.c
 create mode 100644 plugins/messages-dummy.c
 create mode 100644 plugins/messages.h

diff --git a/.gitignore b/.gitignore
index 663240a..e3f5c3f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -29,6 +29,7 @@ src/obexd
 src/obexd.service
 plugins/phonebook.c
 plugins/telephony.c
+plugins/messages.c
 client/obex-client
 client/obex-client.service
 test/obex-test
diff --git a/Makefile.am b/Makefile.am
index d32d613..8d8fdc6 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -58,6 +58,9 @@ builtin_modules += pbap
 builtin_sources += plugins/pbap.c plugins/phonebook.h \
 			plugins/vcard.h plugins/vcard.c
 
+builtin_modules += mas
+builtin_sources += plugins/mas.c plugins/messages.h
+
 builtin_modules += irmc
 builtin_sources += plugins/irmc.c
 
@@ -65,6 +68,7 @@ builtin_modules += syncevolution
 builtin_sources += plugins/syncevolution.c
 
 builtin_nodist += plugins/phonebook.c
+builtin_nodist += plugins/messages.c
 
 libexec_PROGRAMS += src/obexd
 
@@ -137,7 +141,8 @@ CLEANFILES = $(service_DATA) $(builtin_files)
 EXTRA_DIST = src/genbuiltin $(doc_files) $(test_files) src/obex.conf \
 			src/obexd.service.in client/obex-client.service.in \
 			plugins/phonebook-dummy.c plugins/phonebook-ebook.c \
-			plugins/phonebook-tracker.c
+			plugins/phonebook-tracker.c \
+			plugins/messages-dummy.c
 
 DISTCHECK_CONFIGURE_FLAGS = --enable-client --enable-server
 
@@ -150,3 +155,6 @@ MAINTAINERCLEANFILES = Makefile.in \
 
 plugins/phonebook.c: plugins/@PHONEBOOK_DRIVER@
 	$(AM_V_GEN)$(LN_S) @abs_top_srcdir@/$< $@
+
+plugins/messages.c: plugins/@MESSAGES_DRIVER@
+	$(AM_V_GEN)$(LN_S) @abs_top_srcdir@/$< $@
diff --git a/configure.ac b/configure.ac
index 9194843..fb349ae 100644
--- a/configure.ac
+++ b/configure.ac
@@ -106,6 +106,18 @@ AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],
 		CFLAGS="$CFLAGS -g"
 	fi
 ])
+
+messages_driver=dummy
+AC_ARG_WITH(messages, AC_HELP_STRING([--with-messages=DRIVER], [select messages driver]), [
+	if (test "${withval}" = "no"); then
+		messages_driver=dummy;
+	else
+		messages_driver=${withval};
+	fi
+])
+
+AC_SUBST([MESSAGES_DRIVER], [messages-${messages_driver}.c])
+
 phonebook_driver=dummy
 AC_ARG_WITH(phonebook, AC_HELP_STRING([--with-phonebook=DRIVER], [select phonebook driver]), [
 	if (test "${withval}" = "no"); then
diff --git a/plugins/mas.c b/plugins/mas.c
new file mode 100644
index 0000000..cb6dda0
--- /dev/null
+++ b/plugins/mas.c
@@ -0,0 +1,42 @@
+/*
+ *
+ *  OBEX Server
+ *
+ *  Copyright (C) 2010-2011  Slawomir Bochenski <lkslawek@gmail.com>
+ *
+ *
+ *  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 "plugin.h"
+#include "log.h"
+
+#include "messages.h"
+
+static int mas_init(void)
+{
+	return 0;
+}
+
+static void mas_exit(void)
+{
+}
+
+OBEX_PLUGIN_DEFINE(mas, mas_init, mas_exit)
diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
new file mode 100644
index 0000000..1722306
--- /dev/null
+++ b/plugins/messages-dummy.c
@@ -0,0 +1,28 @@
+/*
+ *
+ *  OBEX Server
+ *
+ *  Copyright (C) 2010-2011  Slawomir Bochenski <lkslawek@gmail.com>
+ *
+ *
+ *  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 "messages.h"
diff --git a/plugins/messages.h b/plugins/messages.h
new file mode 100644
index 0000000..2a41ea7
--- /dev/null
+++ b/plugins/messages.h
@@ -0,0 +1,22 @@
+/*
+ *
+ *  OBEX Server
+ *
+ *  Copyright (C) 2010-2011  Slawomir Bochenski <lkslawek@gmail.com>
+ *
+ *
+ *  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
+ *
+ */
diff --git a/src/main.c b/src/main.c
index 1e78615..8154e3b 100644
--- a/src/main.c
+++ b/src/main.c
@@ -84,6 +84,7 @@ static gboolean option_irmc = FALSE;
 static gboolean option_pcsuite = FALSE;
 static gboolean option_symlinks = FALSE;
 static gboolean option_syncevolution = FALSE;
+static gboolean option_mas = FALSE;
 
 static gboolean parse_debug(const char *key, const char *value,
 				gpointer user_data, GError **error)
@@ -125,6 +126,8 @@ static GOptionEntry options[] = {
 				"Enable PC Suite Services server" },
 	{ "syncevolution", 'e', 0, G_OPTION_ARG_NONE, &option_syncevolution,
 				"Enable OBEX server for SyncEvolution" },
+        { "mas", 'm', 0, G_OPTION_ARG_NONE, &option_mas,
+				"Enable Message Access server" },
 	{ NULL },
 };
 
@@ -212,9 +215,10 @@ int main(int argc, char *argv[])
 	if (option_opp == FALSE && option_ftp == FALSE &&
 				option_pbap == FALSE &&
 				option_irmc == FALSE &&
-				option_syncevolution == FALSE) {
+				option_syncevolution == FALSE &&
+				option_mas == FALSE) {
 		fprintf(stderr, "No server selected (use either "
-				"--opp, --ftp, --pbap, --irmc or --syncevolution)\n");
+				"--opp, --ftp, --pbap, --irmc, --mas, or --syncevolution)\n");
 		exit(EXIT_FAILURE);
 	}
 
@@ -278,6 +282,9 @@ int main(int argc, char *argv[])
 		obex_server_init(OBEX_SYNCEVOLUTION, NULL, TRUE, FALSE,
 							FALSE, NULL);
 
+	if (option_mas == TRUE)
+		obex_server_init(OBEX_MAS, NULL, TRUE, FALSE, FALSE, NULL);
+
 	if (!root_folder_setup(option_root, option_root_setup)) {
 		error("Unable to setup root folder %s", option_root);
 		exit(EXIT_FAILURE);
diff --git a/src/obex.h b/src/obex.h
index c3f6e3d..94274c2 100644
--- a/src/obex.h
+++ b/src/obex.h
@@ -36,6 +36,7 @@
 #define OBEX_IRMC	(1 << 5)
 #define OBEX_PCSUITE	(1 << 6)
 #define OBEX_SYNCEVOLUTION	(1 << 7)
+#define OBEX_MAS	(1 << 8)
 
 #define TARGET_SIZE 16
 
-- 
1.7.1


^ permalink raw reply related

* [PATCH 2/4] Add actual service for Message Access Profile
From: lkslawek @ 2011-03-02  9:36 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Slawomir Bochenski
In-Reply-To: <1299058614-8904-1-git-send-email-lkslawek@gmail.com>

From: Slawomir Bochenski <lkslawek@gmail.com>

This adds basic service functionality in MAP code, accompanied by proper
record for SDP.

RFCOMM channel of choice is 16 which is in accordance with
doc/assigned-numbers.txt.
---
 plugins/mas.c |  186 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 186 insertions(+), 0 deletions(-)

diff --git a/plugins/mas.c b/plugins/mas.c
index cb6dda0..2d061a1 100644
--- a/plugins/mas.c
+++ b/plugins/mas.c
@@ -25,18 +25,204 @@
 #include <config.h>
 #endif
 
+#include <errno.h>
+#include <glib.h>
+#include <openobex/obex.h>
+
 #include "plugin.h"
 #include "log.h"
+#include "obex.h"
+#include "service.h"
+#include "dbus.h"
 
 #include "messages.h"
 
+/* Channel number according to bluez doc/assigned-numbers.txt */
+#define MAS_CHANNEL	16
+
+#define MAS_RECORD "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>		\
+<record>								\
+  <attribute id=\"0x0001\">						\
+    <sequence>								\
+      <uuid value=\"0x1132\"/>						\
+    </sequence>								\
+  </attribute>								\
+									\
+  <attribute id=\"0x0004\">						\
+    <sequence>								\
+      <sequence>							\
+        <uuid value=\"0x0100\"/>					\
+      </sequence>							\
+      <sequence>							\
+        <uuid value=\"0x0003\"/>					\
+        <uint8 value=\"%u\" name=\"channel\"/>				\
+      </sequence>							\
+      <sequence>							\
+        <uuid value=\"0x0008\"/>					\
+      </sequence>							\
+    </sequence>								\
+  </attribute>								\
+									\
+  <attribute id=\"0x0009\">						\
+    <sequence>								\
+      <sequence>							\
+        <uuid value=\"0x1134\"/>					\
+        <uint16 value=\"0x0100\" name=\"version\"/>			\
+      </sequence>							\
+    </sequence>								\
+  </attribute>								\
+									\
+  <attribute id=\"0x0100\">						\
+    <text value=\"%s\" name=\"name\"/>					\
+  </attribute>								\
+									\
+  <attribute id=\"0x0315\">						\
+    <uint8 value=\"0x00\"/>						\
+  </attribute>								\
+									\
+  <attribute id=\"0x0316\">						\
+    <uint8 value=\"0x0F\"/>						\
+  </attribute>								\
+</record>"
+
+struct mas_session {
+	struct mas_request *request;
+};
+
+static const uint8_t MAS_TARGET[TARGET_SIZE] = {
+			0xbb, 0x58, 0x2b, 0x40, 0x42, 0x0c, 0x11, 0xdb,
+			0xb0, 0xde, 0x08, 0x00, 0x20, 0x0c, 0x9a, 0x66  };
+
+static void mas_clean(struct mas_session *mas)
+{
+	g_free(mas);
+}
+
+static void *mas_connect(struct obex_session *os, int *err)
+{
+	struct mas_session *mas;
+
+	DBG("");
+
+	*err = 0;
+
+	mas = g_new0(struct mas_session, 1);
+
+	manager_register_session(os);
+
+	return mas;
+}
+
+static void mas_disconnect(struct obex_session *os, void *user_data)
+{
+	struct mas_session *mas = user_data;
+
+	DBG("");
+
+	manager_unregister_session(os);
+
+	mas_clean(mas);
+}
+
+static int mas_get(struct obex_session *os, obex_object_t *obj,
+					gboolean *stream, void *user_data)
+{
+	struct mas_session *mas = user_data;
+	const char *type = obex_get_type(os);
+	const char *name = obex_get_name(os);
+	int ret;
+
+	DBG("GET: name %s type %s mas %p",
+			name, type, mas);
+
+	if (type == NULL)
+		return -EBADR;
+
+	*stream = FALSE;
+
+	ret = obex_get_stream_start(os, name);
+	if (ret < 0)
+		goto fail;
+
+	return 0;
+fail:
+	return ret;
+}
+
+static int mas_put(struct obex_session *os, obex_object_t *obj, void *user_data)
+{
+	struct mas_session *mas = user_data;
+	const char *type = obex_get_type(os);
+	const char *name = obex_get_name(os);
+	int ret;
+
+	DBG("PUT: name %s type %s mas %p", name, type, mas);
+
+	if (type == NULL)
+		return -EBADR;
+
+	ret = obex_put_stream_start(os, name);
+	if (ret < 0)
+		goto fail;
+
+	return 0;
+fail:
+	return ret;
+}
+
+static int mas_setpath(struct obex_session *os, obex_object_t *obj,
+		void *user_data)
+{
+	const char *name;
+	uint8_t *nonhdr;
+
+	if (OBEX_ObjectGetNonHdrData(obj, &nonhdr) != 2) {
+		error("Set path failed: flag and constants not found!");
+		return -EBADR;
+	}
+
+	name = obex_get_name(os);
+
+	DBG("SETPATH: name %s nonhdr 0x%x%x", name, nonhdr[0], nonhdr[1]);
+
+	if ((nonhdr[0] & 0x02) != 0x02) {
+		DBG("Error: requested directory creation");
+		return -EBADR;
+	}
+
+	return 0;
+}
+static struct obex_service_driver mas = {
+	.name = "Message Access server",
+	.service = OBEX_MAS,
+	.channel = MAS_CHANNEL,
+	.record = MAS_RECORD,
+	.target = MAS_TARGET,
+	.target_size = TARGET_SIZE,
+	.connect = mas_connect,
+	.get = mas_get,
+	.put = mas_put,
+	.setpath = mas_setpath,
+	.disconnect = mas_disconnect,
+};
+
 static int mas_init(void)
 {
+	int err;
+
+	err = obex_service_driver_register(&mas);
+	if (err < 0)
+		goto fail_mas_reg;
+
 	return 0;
+
+fail_mas_reg:
+	return err;
 }
 
 static void mas_exit(void)
 {
+	obex_service_driver_unregister(&mas);
 }
 
 OBEX_PLUGIN_DEFINE(mas, mas_init, mas_exit)
-- 
1.7.1


^ 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