Linux bluetooth development
 help / color / mirror / Atom feed
* Re: [PATCH hcidump] amp: Decode Num Completed Data Blocks
From: Andrei Emeltchenko @ 2012-09-25 10:02 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1346398640-8423-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

ping

On Fri, Aug 31, 2012 at 10:37:20AM +0300, Andrei Emeltchenko wrote:
> From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
> 
> Adds decoding Number Of Completed Data Blocks Event
> 
> > HCI Event: Number Of Completed Data Blocks (0x48) plen 9
>     Total num blocks 4 Num handles 1
>       Handle 0x0001: Num complt pkts 1 Num complt blks 1
> ---
>  lib/hci.h    |   10 ++++++++++
>  parser/hci.c |   22 ++++++++++++++++++++++
>  2 files changed, 32 insertions(+)
> 
> diff --git a/lib/hci.h b/lib/hci.h
> index d068a2f..7eacca5 100644
> --- a/lib/hci.h
> +++ b/lib/hci.h
> @@ -2197,6 +2197,16 @@ typedef struct {
>  #define EVT_FLOW_SPEC_MODIFY_COMPLETE_SIZE 3
>  
>  #define EVT_NUMBER_COMPLETED_BLOCKS		0x48
> +typedef struct {
> +	uint16_t		handle;
> +	uint16_t		num_cmplt_pkts;
> +	uint16_t		num_cmplt_blks;
> +} __attribute__ ((packed)) cmplt_handle;
> +typedef struct {
> +	uint16_t		total_num_blocks;
> +	uint8_t			num_handles;
> +	cmplt_handle		handles[0];
> +}  __attribute__ ((packed)) evt_num_completed_blocks;
>  
>  #define EVT_AMP_STATUS_CHANGE			0x4D
>  typedef struct {
> diff --git a/parser/hci.c b/parser/hci.c
> index 38794bd..19cd419 100644
> --- a/parser/hci.c
> +++ b/parser/hci.c
> @@ -3743,6 +3743,25 @@ static inline void flow_spec_modify_dump(int level, struct frame *frm)
>  	}
>  }
>  
> +static inline void num_completed_blocks_dump(int level, struct frame *frm)
> +{
> +	evt_num_completed_blocks *evt = frm->ptr;
> +	int i;
> +
> +	p_indent(level, frm);
> +	printf("Total num blocks %d Num handles %d\n",
> +			btohs(evt->total_num_blocks), evt->num_handles);
> +
> +	for (i = 0; i < evt->num_handles; i++) {
> +		cmplt_handle *h = &evt->handles[i];
> +
> +		p_indent(level + 1, frm);
> +		printf("Handle 0x%4.4x: Num complt pkts %d Num complt blks %d\n",
> +				btohs(h->handle), btohs(h->num_cmplt_pkts),
> +				btohs(h->num_cmplt_blks));
> +	}
> +}
> +
>  static inline void event_dump(int level, struct frame *frm)
>  {
>  	hci_event_hdr *hdr = frm->ptr;
> @@ -3969,6 +3988,9 @@ static inline void event_dump(int level, struct frame *frm)
>  	case EVT_FLOW_SPEC_MODIFY_COMPLETE:
>  		flow_spec_modify_dump(level + 1, frm);
>  		break;
> +	case EVT_NUMBER_COMPLETED_BLOCKS:
> +		num_completed_blocks_dump(level + 1, frm);
> +		break;
>  	default:
>  		raw_dump(level, frm);
>  		break;
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* [PATCHv2 4/4] bluetooth: Remove unneeded batostr function
From: Andrei Emeltchenko @ 2012-09-25  9:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: gustavo
In-Reply-To: <1348566586-28572-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

batostr is not needed anymore since for printing Bluetooth
addresses we use %pMR specifier.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 include/net/bluetooth/bluetooth.h |    1 -
 net/bluetooth/lib.c               |   14 --------------
 2 files changed, 15 deletions(-)

diff --git a/include/net/bluetooth/bluetooth.h b/include/net/bluetooth/bluetooth.h
index ede0369..2554b3f 100644
--- a/include/net/bluetooth/bluetooth.h
+++ b/include/net/bluetooth/bluetooth.h
@@ -180,7 +180,6 @@ static inline void bacpy(bdaddr_t *dst, bdaddr_t *src)
 }
 
 void baswap(bdaddr_t *dst, bdaddr_t *src);
-char *batostr(bdaddr_t *ba);
 
 /* Common socket structures and functions */
 
diff --git a/net/bluetooth/lib.c b/net/bluetooth/lib.c
index e1c9752..b3fbc73 100644
--- a/net/bluetooth/lib.c
+++ b/net/bluetooth/lib.c
@@ -41,20 +41,6 @@ void baswap(bdaddr_t *dst, bdaddr_t *src)
 }
 EXPORT_SYMBOL(baswap);
 
-char *batostr(bdaddr_t *ba)
-{
-	static char str[2][18];
-	static int i = 1;
-
-	i ^= 1;
-	sprintf(str[i], "%2.2X:%2.2X:%2.2X:%2.2X:%2.2X:%2.2X",
-		ba->b[5], ba->b[4], ba->b[3],
-		ba->b[2], ba->b[1], ba->b[0]);
-
-	return str[i];
-}
-EXPORT_SYMBOL(batostr);
-
 /* Bluetooth error codes to Unix errno mapping */
 int bt_to_errno(__u16 code)
 {
-- 
1.7.9.5


^ permalink raw reply related

* [PATCHv2 3/4] Bluetooth: Use %pMR instead of baswap in seq_show
From: Andrei Emeltchenko @ 2012-09-25  9:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: gustavo
In-Reply-To: <1348566586-28572-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Use new bluetooth address print specifier %pMR for printing
bluetooth addresses instead of dedicated variable and baswap.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Acked-by: Marcel Holtmann <marcel@holtmann.org>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
---
 net/bluetooth/af_bluetooth.c |   10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
index 9d49ee6..a9ad589 100644
--- a/net/bluetooth/af_bluetooth.c
+++ b/net/bluetooth/af_bluetooth.c
@@ -569,7 +569,6 @@ static int bt_seq_show(struct seq_file *seq, void *v)
 {
 	struct bt_seq_state *s = seq->private;
 	struct bt_sock_list *l = s->l;
-	bdaddr_t src_baswapped, dst_baswapped;
 
 	if (v == SEQ_START_TOKEN) {
 		seq_puts(seq ,"sk               RefCnt Rmem   Wmem   User   Inode  Src Dst Parent");
@@ -583,18 +582,17 @@ static int bt_seq_show(struct seq_file *seq, void *v)
 	} else {
 		struct sock *sk = sk_entry(v);
 		struct bt_sock *bt = bt_sk(sk);
-		baswap(&src_baswapped, &bt->src);
-		baswap(&dst_baswapped, &bt->dst);
 
-		seq_printf(seq, "%pK %-6d %-6u %-6u %-6u %-6lu %pM %pM %-6lu",
+		seq_printf(seq,
+			   "%pK %-6d %-6u %-6u %-6u %-6lu %pMR %pMR %-6lu",
 			   sk,
 			   atomic_read(&sk->sk_refcnt),
 			   sk_rmem_alloc_get(sk),
 			   sk_wmem_alloc_get(sk),
 			   sock_i_uid(sk),
 			   sock_i_ino(sk),
-			   &src_baswapped,
-			   &dst_baswapped,
+			   &bt->src,
+			   &bt->dst,
 			   bt->parent? sock_i_ino(bt->parent): 0LU);
 
 		if (l->custom_seq_show) {
-- 
1.7.9.5


^ permalink raw reply related

* [PATCHv2 2/4] Bluetooth: Use %pMR in sprintf/seq_printf  instead of batostr
From: Andrei Emeltchenko @ 2012-09-25  9:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: gustavo
In-Reply-To: <1348566586-28572-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Instead of old unsafe batostr function use %pMR print specifier
for printing Bluetooth addresses in sprintf and seq_printf
statements.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 net/bluetooth/cmtp/core.c   |    2 +-
 net/bluetooth/hci_sysfs.c   |   10 +++++-----
 net/bluetooth/hidp/core.c   |    8 ++++++--
 net/bluetooth/l2cap_core.c  |   11 +++++------
 net/bluetooth/rfcomm/core.c |    9 ++++-----
 net/bluetooth/rfcomm/sock.c |    7 +++----
 net/bluetooth/rfcomm/tty.c  |    2 +-
 net/bluetooth/sco.c         |    4 ++--
 8 files changed, 27 insertions(+), 26 deletions(-)

diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c
index 6c9c1fd..e0a6ebf 100644
--- a/net/bluetooth/cmtp/core.c
+++ b/net/bluetooth/cmtp/core.c
@@ -353,7 +353,7 @@ int cmtp_add_connection(struct cmtp_connadd_req *req, struct socket *sock)
 
 	BT_DBG("mtu %d", session->mtu);
 
-	sprintf(session->name, "%s", batostr(&bt_sk(sock->sk)->dst));
+	sprintf(session->name, "%pMR", &bt_sk(sock->sk)->dst);
 
 	session->sock  = sock;
 	session->state = BT_CONFIG;
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index a20e61c..55cceee 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -38,7 +38,7 @@ static ssize_t show_link_address(struct device *dev,
 				 struct device_attribute *attr, char *buf)
 {
 	struct hci_conn *conn = to_hci_conn(dev);
-	return sprintf(buf, "%s\n", batostr(&conn->dst));
+	return sprintf(buf, "%pMR\n", &conn->dst);
 }
 
 static ssize_t show_link_features(struct device *dev,
@@ -224,7 +224,7 @@ static ssize_t show_address(struct device *dev,
 			    struct device_attribute *attr, char *buf)
 {
 	struct hci_dev *hdev = to_hci_dev(dev);
-	return sprintf(buf, "%s\n", batostr(&hdev->bdaddr));
+	return sprintf(buf, "%pMR\n", &hdev->bdaddr);
 }
 
 static ssize_t show_features(struct device *dev,
@@ -406,8 +406,8 @@ static int inquiry_cache_show(struct seq_file *f, void *p)
 
 	list_for_each_entry(e, &cache->all, all) {
 		struct inquiry_data *data = &e->data;
-		seq_printf(f, "%s %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
-			   batostr(&data->bdaddr),
+		seq_printf(f, "%pMR %d %d %d 0x%.2x%.2x%.2x 0x%.4x %d %d %u\n",
+			   &data->bdaddr,
 			   data->pscan_rep_mode, data->pscan_period_mode,
 			   data->pscan_mode, data->dev_class[2],
 			   data->dev_class[1], data->dev_class[0],
@@ -440,7 +440,7 @@ static int blacklist_show(struct seq_file *f, void *p)
 	hci_dev_lock(hdev);
 
 	list_for_each_entry(b, &hdev->blacklist, list)
-		seq_printf(f, "%s\n", batostr(&b->bdaddr));
+		seq_printf(f, "%pMR\n", &b->bdaddr);
 
 	hci_dev_unlock(hdev);
 
diff --git a/net/bluetooth/hidp/core.c b/net/bluetooth/hidp/core.c
index ccd985d..0c00284 100644
--- a/net/bluetooth/hidp/core.c
+++ b/net/bluetooth/hidp/core.c
@@ -932,8 +932,12 @@ static int hidp_setup_hid(struct hidp_session *session,
 	hid->country = req->country;
 
 	strncpy(hid->name, req->name, 128);
-	strncpy(hid->phys, batostr(&bt_sk(session->ctrl_sock->sk)->src), 64);
-	strncpy(hid->uniq, batostr(&bt_sk(session->ctrl_sock->sk)->dst), 64);
+
+	snprintf(hid->phys, sizeof(hid->phys), "%pMR",
+		 &bt_sk(session->ctrl_sock->sk)->src);
+
+	snprintf(hid->uniq, sizeof(hid->uniq), "%pMR",
+		 &bt_sk(session->ctrl_sock->sk)->dst);
 
 	hid->dev.parent = &session->conn->dev;
 	hid->ll_driver = &hidp_hid_driver;
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 3de48c9..0873345 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -5623,12 +5623,11 @@ static int l2cap_debugfs_show(struct seq_file *f, void *p)
 	list_for_each_entry(c, &chan_list, global_l) {
 		struct sock *sk = c->sk;
 
-		seq_printf(f, "%s %s %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
-					batostr(&bt_sk(sk)->src),
-					batostr(&bt_sk(sk)->dst),
-					c->state, __le16_to_cpu(c->psm),
-					c->scid, c->dcid, c->imtu, c->omtu,
-					c->sec_level, c->mode);
+		seq_printf(f, "%pMR %pMR %d %d 0x%4.4x 0x%4.4x %d %d %d %d\n",
+			   &bt_sk(sk)->src, &bt_sk(sk)->dst,
+			   c->state, __le16_to_cpu(c->psm),
+			   c->scid, c->dcid, c->imtu, c->omtu,
+			   c->sec_level, c->mode);
 	}
 
 	read_unlock(&chan_list_lock);
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index f6d066c..fb1d83d 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -2125,11 +2125,10 @@ static int rfcomm_dlc_debugfs_show(struct seq_file *f, void *x)
 		list_for_each_entry(d, &s->dlcs, list) {
 			struct sock *sk = s->sock->sk;
 
-			seq_printf(f, "%s %s %ld %d %d %d %d\n",
-						batostr(&bt_sk(sk)->src),
-						batostr(&bt_sk(sk)->dst),
-						d->state, d->dlci, d->mtu,
-						d->rx_credits, d->tx_credits);
+			seq_printf(f, "%pMR %pMR %ld %d %d %d %d\n",
+				   &bt_sk(sk)->src, &bt_sk(sk)->dst,
+				   d->state, d->dlci, d->mtu,
+				   d->rx_credits, d->tx_credits);
 		}
 	}
 
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index ebd2f57..867a065 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -973,10 +973,9 @@ static int rfcomm_sock_debugfs_show(struct seq_file *f, void *p)
 	read_lock(&rfcomm_sk_list.lock);
 
 	sk_for_each(sk, node, &rfcomm_sk_list.head) {
-		seq_printf(f, "%s %s %d %d\n",
-				batostr(&bt_sk(sk)->src),
-				batostr(&bt_sk(sk)->dst),
-				sk->sk_state, rfcomm_pi(sk)->channel);
+		seq_printf(f, "%pMR %pMR %d %d\n",
+			   &bt_sk(sk)->src, &bt_sk(sk)->dst,
+			   sk->sk_state, rfcomm_pi(sk)->channel);
 	}
 
 	read_unlock(&rfcomm_sk_list.lock);
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 0e487e9..6baf64d 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -166,7 +166,7 @@ static struct device *rfcomm_get_device(struct rfcomm_dev *dev)
 static ssize_t show_address(struct device *tty_dev, struct device_attribute *attr, char *buf)
 {
 	struct rfcomm_dev *dev = dev_get_drvdata(tty_dev);
-	return sprintf(buf, "%s\n", batostr(&dev->dst));
+	return sprintf(buf, "%pMR\n", &dev->dst);
 }
 
 static ssize_t show_channel(struct device *tty_dev, struct device_attribute *attr, char *buf)
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index 347d3b9..450cdcd 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -959,8 +959,8 @@ static int sco_debugfs_show(struct seq_file *f, void *p)
 	read_lock(&sco_sk_list.lock);
 
 	sk_for_each(sk, node, &sco_sk_list.head) {
-		seq_printf(f, "%s %s %d\n", batostr(&bt_sk(sk)->src),
-			   batostr(&bt_sk(sk)->dst), sk->sk_state);
+		seq_printf(f, "%pMR %pMR %d\n", &bt_sk(sk)->src,
+			   &bt_sk(sk)->dst, sk->sk_state);
 	}
 
 	read_unlock(&sco_sk_list.lock);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCHv2 1/4] Bluetooth: Use %pMR in debug instead of batostr
From: Andrei Emeltchenko @ 2012-09-25  9:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: gustavo
In-Reply-To: <1348566586-28572-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

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

Instead of old unsafe batostr function use %pMR print specifier
for printing Bluetooth addresses in debug and error statements.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
---
 net/bluetooth/bnep/core.c   |    3 +--
 net/bluetooth/hci_conn.c    |    6 +++---
 net/bluetooth/hci_core.c    |   22 +++++++++++-----------
 net/bluetooth/hci_event.c   |   15 +++++++--------
 net/bluetooth/l2cap_core.c  |    6 +++---
 net/bluetooth/rfcomm/core.c |    6 +++---
 net/bluetooth/rfcomm/sock.c |    2 +-
 net/bluetooth/rfcomm/tty.c  |    4 ++--
 net/bluetooth/sco.c         |    8 ++++----
 9 files changed, 35 insertions(+), 37 deletions(-)

diff --git a/net/bluetooth/bnep/core.c b/net/bluetooth/bnep/core.c
index 4a6620b..a5b6397 100644
--- a/net/bluetooth/bnep/core.c
+++ b/net/bluetooth/bnep/core.c
@@ -182,8 +182,7 @@ static int bnep_ctrl_set_mcfilter(struct bnep_session *s, u8 *data, int len)
 			a2 = data;
 			data += ETH_ALEN;
 
-			BT_DBG("mc filter %s -> %s",
-				batostr((void *) a1), batostr((void *) a2));
+			BT_DBG("mc filter %pMR -> %pMR", a1, a2);
 
 			/* Iterate from a1 to a2 */
 			set_bit(bnep_mc_hash(a1), (ulong *) &s->mc_filter);
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c
index b9196a4..53202f6 100644
--- a/net/bluetooth/hci_conn.c
+++ b/net/bluetooth/hci_conn.c
@@ -320,7 +320,7 @@ struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
 {
 	struct hci_conn *conn;
 
-	BT_DBG("%s dst %s", hdev->name, batostr(dst));
+	BT_DBG("%s dst %pMR", hdev->name, dst);
 
 	conn = kzalloc(sizeof(struct hci_conn), GFP_KERNEL);
 	if (!conn)
@@ -437,7 +437,7 @@ struct hci_dev *hci_get_route(bdaddr_t *dst, bdaddr_t *src)
 	int use_src = bacmp(src, BDADDR_ANY);
 	struct hci_dev *hdev = NULL, *d;
 
-	BT_DBG("%s -> %s", batostr(src), batostr(dst));
+	BT_DBG("%pMR -> %pMR", src, dst);
 
 	read_lock(&hci_dev_list_lock);
 
@@ -567,7 +567,7 @@ static struct hci_conn *hci_connect_sco(struct hci_dev *hdev, int type,
 struct hci_conn *hci_connect(struct hci_dev *hdev, int type, bdaddr_t *dst,
 			     __u8 dst_type, __u8 sec_level, __u8 auth_type)
 {
-	BT_DBG("%s dst %s type 0x%x", hdev->name, batostr(dst), type);
+	BT_DBG("%s dst %pMR type 0x%x", hdev->name, dst, type);
 
 	switch (type) {
 	case LE_LINK:
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index 3588f31..bd26cb5 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -405,7 +405,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup(struct hci_dev *hdev,
 	struct discovery_state *cache = &hdev->discovery;
 	struct inquiry_entry *e;
 
-	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
+	BT_DBG("cache %p, %pMR", cache, bdaddr);
 
 	list_for_each_entry(e, &cache->all, all) {
 		if (!bacmp(&e->data.bdaddr, bdaddr))
@@ -421,7 +421,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_unknown(struct hci_dev *hdev,
 	struct discovery_state *cache = &hdev->discovery;
 	struct inquiry_entry *e;
 
-	BT_DBG("cache %p, %s", cache, batostr(bdaddr));
+	BT_DBG("cache %p, %pMR", cache, bdaddr);
 
 	list_for_each_entry(e, &cache->unknown, list) {
 		if (!bacmp(&e->data.bdaddr, bdaddr))
@@ -438,7 +438,7 @@ struct inquiry_entry *hci_inquiry_cache_lookup_resolve(struct hci_dev *hdev,
 	struct discovery_state *cache = &hdev->discovery;
 	struct inquiry_entry *e;
 
-	BT_DBG("cache %p bdaddr %s state %d", cache, batostr(bdaddr), state);
+	BT_DBG("cache %p bdaddr %pMR state %d", cache, bdaddr, state);
 
 	list_for_each_entry(e, &cache->resolve, list) {
 		if (!bacmp(bdaddr, BDADDR_ANY) && e->name_state == state)
@@ -475,7 +475,7 @@ bool hci_inquiry_cache_update(struct hci_dev *hdev, struct inquiry_data *data,
 	struct discovery_state *cache = &hdev->discovery;
 	struct inquiry_entry *ie;
 
-	BT_DBG("cache %p, %s", cache, batostr(&data->bdaddr));
+	BT_DBG("cache %p, %pMR", cache, &data->bdaddr);
 
 	if (ssp)
 		*ssp = data->ssp_mode;
@@ -1257,7 +1257,7 @@ int hci_add_link_key(struct hci_dev *hdev, struct hci_conn *conn, int new_key,
 		list_add(&key->list, &hdev->link_keys);
 	}
 
-	BT_DBG("%s key for %s type %u", hdev->name, batostr(bdaddr), type);
+	BT_DBG("%s key for %pMR type %u", hdev->name, bdaddr, type);
 
 	/* Some buggy controller combinations generate a changed
 	 * combination key for legacy pairing even when there's no
@@ -1336,7 +1336,7 @@ int hci_remove_link_key(struct hci_dev *hdev, bdaddr_t *bdaddr)
 	if (!key)
 		return -ENOENT;
 
-	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
+	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
 
 	list_del(&key->list);
 	kfree(key);
@@ -1352,7 +1352,7 @@ int hci_remove_ltk(struct hci_dev *hdev, bdaddr_t *bdaddr)
 		if (bacmp(bdaddr, &k->bdaddr))
 			continue;
 
-		BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
+		BT_DBG("%s removing %pMR", hdev->name, bdaddr);
 
 		list_del(&k->list);
 		kfree(k);
@@ -1399,7 +1399,7 @@ int hci_remove_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr)
 	if (!data)
 		return -ENOENT;
 
-	BT_DBG("%s removing %s", hdev->name, batostr(bdaddr));
+	BT_DBG("%s removing %pMR", hdev->name, bdaddr);
 
 	list_del(&data->list);
 	kfree(data);
@@ -1438,7 +1438,7 @@ int hci_add_remote_oob_data(struct hci_dev *hdev, bdaddr_t *bdaddr, u8 *hash,
 	memcpy(data->hash, hash, sizeof(data->hash));
 	memcpy(data->randomizer, randomizer, sizeof(data->randomizer));
 
-	BT_DBG("%s for %s", hdev->name, batostr(bdaddr));
+	BT_DBG("%s for %pMR", hdev->name, bdaddr);
 
 	return 0;
 }
@@ -2309,8 +2309,8 @@ static void hci_link_tx_to(struct hci_dev *hdev, __u8 type)
 	/* Kill stalled connections */
 	list_for_each_entry_rcu(c, &h->list, list) {
 		if (c->type == type && c->sent) {
-			BT_ERR("%s killing stalled connection %s",
-			       hdev->name, batostr(&c->dst));
+			BT_ERR("%s killing stalled connection %pMR",
+			       hdev->name, &c->dst);
 			hci_acl_disconn(c, HCI_ERROR_REMOTE_USER_TERM);
 		}
 	}
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c
index 2022b43..6f2b519 100644
--- a/net/bluetooth/hci_event.c
+++ b/net/bluetooth/hci_event.c
@@ -1210,7 +1210,7 @@ static void hci_cs_create_conn(struct hci_dev *hdev, __u8 status)
 
 	conn = hci_conn_hash_lookup_ba(hdev, ACL_LINK, &cp->bdaddr);
 
-	BT_DBG("%s bdaddr %s hcon %p", hdev->name, batostr(&cp->bdaddr), conn);
+	BT_DBG("%s bdaddr %pMR hcon %p", hdev->name, &cp->bdaddr, conn);
 
 	if (status) {
 		if (conn && conn->state == BT_CONNECT) {
@@ -1639,8 +1639,7 @@ static void hci_cs_le_create_conn(struct hci_dev *hdev, __u8 status)
 			return;
 		}
 
-		BT_DBG("%s bdaddr %s conn %p", hdev->name, batostr(&conn->dst),
-		       conn);
+		BT_DBG("%s bdaddr %pMR conn %p", hdev->name, &conn->dst, conn);
 
 		conn->state = BT_CLOSED;
 		mgmt_connect_failed(hdev, &conn->dst, conn->type,
@@ -1822,7 +1821,7 @@ static void hci_conn_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 	struct hci_ev_conn_request *ev = (void *) skb->data;
 	int mask = hdev->link_mode;
 
-	BT_DBG("%s bdaddr %s type 0x%x", hdev->name, batostr(&ev->bdaddr),
+	BT_DBG("%s bdaddr %pMR type 0x%x", hdev->name, &ev->bdaddr,
 	       ev->link_type);
 
 	mask |= hci_proto_connect_ind(hdev, &ev->bdaddr, ev->link_type);
@@ -2705,13 +2704,13 @@ static void hci_link_key_request_evt(struct hci_dev *hdev, struct sk_buff *skb)
 
 	key = hci_find_link_key(hdev, &ev->bdaddr);
 	if (!key) {
-		BT_DBG("%s link key not found for %s", hdev->name,
-		       batostr(&ev->bdaddr));
+		BT_DBG("%s link key not found for %pMR", hdev->name,
+		       &ev->bdaddr);
 		goto not_found;
 	}
 
-	BT_DBG("%s found key type %u for %s", hdev->name, key->type,
-	       batostr(&ev->bdaddr));
+	BT_DBG("%s found key type %u for %pMR", hdev->name, key->type,
+	       &ev->bdaddr);
 
 	if (!test_bit(HCI_DEBUG_KEYS, &hdev->dev_flags) &&
 	    key->type == HCI_LK_DEBUG_COMBINATION) {
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 2073045..3de48c9 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1448,7 +1448,7 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
 	__u8 auth_type;
 	int err;
 
-	BT_DBG("%s -> %s (type %u) psm 0x%2.2x", batostr(src), batostr(dst),
+	BT_DBG("%pMR -> %pMR (type %u) psm 0x%2.2x", src, dst,
 	       dst_type, __le16_to_cpu(psm));
 
 	hdev = hci_get_route(dst, src);
@@ -5329,7 +5329,7 @@ int l2cap_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
 	int exact = 0, lm1 = 0, lm2 = 0;
 	struct l2cap_chan *c;
 
-	BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
+	BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
 
 	/* Find listening sockets and check their link_mode */
 	read_lock(&chan_list_lock);
@@ -5359,7 +5359,7 @@ void l2cap_connect_cfm(struct hci_conn *hcon, u8 status)
 {
 	struct l2cap_conn *conn;
 
-	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
+	BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
 
 	if (!status) {
 		conn = l2cap_conn_add(hcon, status);
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index c75107e..f6d066c 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -377,8 +377,8 @@ static int __rfcomm_dlc_open(struct rfcomm_dlc *d, bdaddr_t *src, bdaddr_t *dst,
 	int err = 0;
 	u8 dlci;
 
-	BT_DBG("dlc %p state %ld %s %s channel %d",
-			d, d->state, batostr(src), batostr(dst), channel);
+	BT_DBG("dlc %p state %ld %pMR -> %pMR channel %d",
+	       d, d->state, src, dst, channel);
 
 	if (channel < 1 || channel > 30)
 		return -EINVAL;
@@ -676,7 +676,7 @@ static struct rfcomm_session *rfcomm_session_create(bdaddr_t *src,
 	struct socket *sock;
 	struct sock *sk;
 
-	BT_DBG("%s %s", batostr(src), batostr(dst));
+	BT_DBG("%pMR -> %pMR", src, dst);
 
 	*err = rfcomm_l2sock_create(&sock);
 	if (*err < 0)
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c
index 260821a..ebd2f57 100644
--- a/net/bluetooth/rfcomm/sock.c
+++ b/net/bluetooth/rfcomm/sock.c
@@ -334,7 +334,7 @@ static int rfcomm_sock_bind(struct socket *sock, struct sockaddr *addr, int addr
 	struct sock *sk = sock->sk;
 	int err = 0;
 
-	BT_DBG("sk %p %s", sk, batostr(&sa->rc_bdaddr));
+	BT_DBG("sk %p %pMR", sk, &sa->rc_bdaddr);
 
 	if (!addr || addr->sa_family != AF_BLUETOOTH)
 		return -EINVAL;
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index cb96077..0e487e9 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -663,8 +663,8 @@ static int rfcomm_tty_open(struct tty_struct *tty, struct file *filp)
 	if (!dev)
 		return -ENODEV;
 
-	BT_DBG("dev %p dst %s channel %d opened %d", dev, batostr(&dev->dst),
-				dev->channel, dev->port.count);
+	BT_DBG("dev %p dst %pMR channel %d opened %d", dev, &dev->dst,
+	       dev->channel, dev->port.count);
 
 	spin_lock_irqsave(&dev->port.lock, flags);
 	if (++dev->port.count > 1) {
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c
index dc42b91..347d3b9 100644
--- a/net/bluetooth/sco.c
+++ b/net/bluetooth/sco.c
@@ -172,7 +172,7 @@ static int sco_connect(struct sock *sk)
 	struct hci_dev  *hdev;
 	int err, type;
 
-	BT_DBG("%s -> %s", batostr(src), batostr(dst));
+	BT_DBG("%pMR -> %pMR", src, dst);
 
 	hdev = hci_get_route(dst, src);
 	if (!hdev)
@@ -460,7 +460,7 @@ static int sco_sock_bind(struct socket *sock, struct sockaddr *addr, int addr_le
 	struct sock *sk = sock->sk;
 	int err = 0;
 
-	BT_DBG("sk %p %s", sk, batostr(&sa->sco_bdaddr));
+	BT_DBG("sk %p %pMR", sk, &sa->sco_bdaddr);
 
 	if (!addr || addr->sa_family != AF_BLUETOOTH)
 		return -EINVAL;
@@ -893,7 +893,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
 	struct hlist_node *node;
 	int lm = 0;
 
-	BT_DBG("hdev %s, bdaddr %s", hdev->name, batostr(bdaddr));
+	BT_DBG("hdev %s, bdaddr %pMR", hdev->name, bdaddr);
 
 	/* Find listening sockets */
 	read_lock(&sco_sk_list.lock);
@@ -914,7 +914,7 @@ int sco_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr)
 
 void sco_connect_cfm(struct hci_conn *hcon, __u8 status)
 {
-	BT_DBG("hcon %p bdaddr %s status %d", hcon, batostr(&hcon->dst), status);
+	BT_DBG("hcon %p bdaddr %pMR status %d", hcon, &hcon->dst, status);
 	if (!status) {
 		struct sco_conn *conn;
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCHv2 0/4] Remove unsafe batostr
From: Andrei Emeltchenko @ 2012-09-25  9:49 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: gustavo
In-Reply-To: <20120821175534.GD17005@joana>

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

Since the patch "vsprintf: add %pMR for Bluetooth MAC address" in in bluetooth-next resend the patch series.

Changes:
	* v2: Rebase against recent bluetooth-next.

Andrei Emeltchenko (4):
  Bluetooth: Use %pMR in debug instead of batostr
  Bluetooth: Use %pMR in sprintf/seq_printf  instead of batostr
  Bluetooth: Use %pMR instead of baswap in seq_show
  bluetooth: Remove unneeded batostr function

 include/net/bluetooth/bluetooth.h |    1 -
 net/bluetooth/af_bluetooth.c      |   10 ++++------
 net/bluetooth/bnep/core.c         |    3 +--
 net/bluetooth/cmtp/core.c         |    2 +-
 net/bluetooth/hci_conn.c          |    6 +++---
 net/bluetooth/hci_core.c          |   22 +++++++++++-----------
 net/bluetooth/hci_event.c         |   15 +++++++--------
 net/bluetooth/hci_sysfs.c         |   10 +++++-----
 net/bluetooth/hidp/core.c         |    8 ++++++--
 net/bluetooth/l2cap_core.c        |   17 ++++++++---------
 net/bluetooth/lib.c               |   14 --------------
 net/bluetooth/rfcomm/core.c       |   15 +++++++--------
 net/bluetooth/rfcomm/sock.c       |    9 ++++-----
 net/bluetooth/rfcomm/tty.c        |    6 +++---
 net/bluetooth/sco.c               |   12 ++++++------
 15 files changed, 66 insertions(+), 84 deletions(-)

-- 
1.7.9.5


^ permalink raw reply

* [PATCH v0] audio: Fix crash if gateway closed before reply
From: Mikel Astiz @ 2012-09-25  9:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Mikel Astiz

From: Mikel Astiz <mikel.astiz@bmw-carit.de>

The audio gateway can be closed (dev->gateway == NULL) before the reply
from the agent has been received, resulting in the following crash as
reproduced while removing (unpairing) a device:

bluetoothd[2219]: src/mgmt.c:mgmt_unpair_device() index 0 addr 38:16:D1:C5:D1:A2
bluetoothd[2219]: audio/gateway.c:path_unregister() Unregistered interface org.bluez.HandsfreeGateway on path /org/bluez/2219/hci0/dev_38_16_D1_C5_D1_A2
bluetoothd[2219]: audio/media.c:gateway_state_changed()
bluetoothd[2219]: audio/media.c:gateway_state_changed() Clear endpoint 0x555555820640
bluetoothd[2219]: audio/source.c:path_unregister() Unregistered interface org.bluez.AudioSource on path /org/bluez/2219/hci0/dev_38_16_D1_C5_D1_A2
bluetoothd[2219]: src/device.c:btd_device_unref() 0x555555833e70: ref=1
bluetoothd[2219]: src/adapter.c:adapter_get_device() 38:16:D1:C5:D1:A2
bluetoothd[2219]: src/adapter.c:adapter_create_device() 38:16:D1:C5:D1:A2
bluetoothd[2219]: src/device.c:device_create() Creating device /org/bluez/2219/hci0/dev_38_16_D1_C5_D1_A2
bluetoothd[2219]: src/device.c:device_free() 0x55555581f9c0
bluetoothd[2219]: Unable to get btd_device object for 38:16:D1:C5:D1:A2
bluetoothd[2219]: src/device.c:btd_device_unref() 0x555555833e70: ref=0
bluetoothd[2219]: src/device.c:device_free() 0x555555833e70
bluetoothd[2219]: src/mgmt.c:mgmt_event() cond 1
bluetoothd[2219]: src/mgmt.c:mgmt_event() Received 16 bytes from management socket
bluetoothd[2219]: src/mgmt.c:mgmt_cmd_complete()
bluetoothd[2219]: src/mgmt.c:mgmt_cmd_complete() unpair_device complete

Program received signal SIGSEGV, Segmentation fault.
0x000055555556fa26 in newconnection_reply (call=<optimized out>, data=0x555555824dd0) at audio/gateway.c:285
285		if (!dev->gateway->rfcomm) {
---
 audio/gateway.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/audio/gateway.c b/audio/gateway.c
index 45b25a1..6990573 100644
--- a/audio/gateway.c
+++ b/audio/gateway.c
@@ -282,6 +282,11 @@ static void newconnection_reply(DBusPendingCall *call, void *data)
 	DBusMessage *reply = dbus_pending_call_steal_reply(call);
 	DBusError derr;
 
+	if (gw == NULL) {
+		DBG("Gateway closed before agent reply");
+		goto done;
+	}
+
 	if (!dev->gateway->rfcomm) {
 		DBG("RFCOMM disconnected from server before agent reply");
 		goto done;
-- 
1.7.7.6


^ permalink raw reply related

* Re: [PATCH obexd] MAP: Add Notification Registration support
From: Luiz Augusto von Dentz @ 2012-09-25  8:22 UTC (permalink / raw)
  To: Sunil Kumar Behera; +Cc: linux-bluetooth
In-Reply-To: <1347892917-13013-1-git-send-email-sunil.behera@samsung.com>

Hi Sunil,

On Mon, Sep 17, 2012 at 5:41 PM, Sunil Kumar Behera
<sunil.behera@samsung.com> wrote:
> This feature allows the MCE to set the notification mode
> on the MSE side.
> ---
>  plugins/mas.c              |   50 ++++++++++++++++++++++++++++++++++++++++++--
>  plugins/messages-dummy.c   |    6 ++----
>  plugins/messages-tracker.c |    6 ++----
>  plugins/messages.h         |   17 +++++++--------
>  4 files changed, 60 insertions(+), 19 deletions(-)
>
> diff --git a/plugins/mas.c b/plugins/mas.c
> index 186d267..977e5a1 100644
> --- a/plugins/mas.c
> +++ b/plugins/mas.c
> @@ -119,6 +119,8 @@ struct mas_session {
>         GObexApparam *inparams;
>         GObexApparam *outparams;
>         gboolean ap_sent;
> +       uint8_t notification_status;
> +       char *remote_addr;
>  };
>
>  static const uint8_t MAS_TARGET[TARGET_SIZE] = {
> @@ -167,12 +169,14 @@ static void reset_request(struct mas_session *mas)
>  static void mas_clean(struct mas_session *mas)
>  {
>         reset_request(mas);
> +       g_free(mas->remote_addr);
>         g_free(mas);
>  }
>
>  static void *mas_connect(struct obex_session *os, int *err)
>  {
>         struct mas_session *mas;
> +       char *address;
>
>         DBG("");
>
> @@ -184,6 +188,9 @@ static void *mas_connect(struct obex_session *os, int *err)
>
>         manager_register_session(os);
>
> +       if (obex_getpeername(os, &address) == 0)
> +               mas->remote_addr = address;
> +
>         return mas;
>
>  failed:
> @@ -695,6 +702,45 @@ static void *message_set_status_open(const char *name, int oflag, mode_t mode,
>         return mas;
>  }
>
> +static void *notification_registration_open(const char *name, int oflag,
> +                                               mode_t mode, void *driver_data,
> +                                               size_t *size, int *err)
> +{
> +       struct mas_session *mas = driver_data;
> +       uint8_t status;
> +
> +       if (oflag == O_RDONLY) {
> +               *err = -EBADR;
> +               return NULL;
> +       }
> +
> +       if (!g_obex_apparam_get_uint8(mas->inparams, MAP_AP_NOTIFICATIONSTATUS,
> +                                                               &status)) {
> +               *err = -EBADR;
> +               return NULL;
> +       }
> +
> +       *err = 0;
> +       mas->notification_status = status;
> +       mas->finished = TRUE;
> +       return mas;
> +}
> +
> +static int notification_registration_close(void *obj)
> +{
> +       struct mas_session *mas = obj;
> +
> +       DBG("");
> +
> +       messages_set_notification_registration(mas->backend_data,
> +                                               mas->remote_addr,
> +                                               mas->notification_status, mas);
> +
> +       reset_request(mas);
> +
> +       return 0;
> +}
> +
>  static ssize_t any_get_next_header(void *object, void *buf, size_t mtu,
>                                                                 uint8_t *hi)
>  {
> @@ -820,8 +866,8 @@ static struct obex_mime_type_driver mime_notification_registration = {
>         .target = MAS_TARGET,
>         .target_size = TARGET_SIZE,
>         .mimetype = "x-bt/MAP-NotificationRegistration",
> -       .open = any_open,
> -       .close = any_close,
> +       .open = notification_registration_open,
> +       .close = notification_registration_close,
>         .read = any_read,
>         .write = any_write,
>  };
> diff --git a/plugins/messages-dummy.c b/plugins/messages-dummy.c
> index 4c66f51..ecbe894 100644
> --- a/plugins/messages-dummy.c
> +++ b/plugins/messages-dummy.c
> @@ -251,10 +251,8 @@ void messages_disconnect(void *s)
>         g_free(session);
>  }
>
> -int messages_set_notification_registration(void *session,
> -               void (*send_event)(void *session,
> -                       const struct messages_event *event, void *user_data),
> -               void *user_data)
> +int messages_set_notification_registration(void *session, char *address,
> +                                               uint8_t status, void *user_data)
>  {
>         return -ENOSYS;
>  }
> diff --git a/plugins/messages-tracker.c b/plugins/messages-tracker.c
> index 2c7541b..aa62870 100644
> --- a/plugins/messages-tracker.c
> +++ b/plugins/messages-tracker.c
> @@ -180,10 +180,8 @@ void messages_disconnect(void *s)
>         g_free(session);
>  }
>
> -int messages_set_notification_registration(void *session,
> -               void (*send_event)(void *session,
> -                       const struct messages_event *event, void *user_data),
> -               void *user_data)
> +int messages_set_notification_registration(void *session, char *address,
> +                                               uint8_t status, void *user_data)
>  {
>         return -ENOSYS;
>  }
> diff --git a/plugins/messages.h b/plugins/messages.h
> index 00a16b1..0fe5cc3 100644
> --- a/plugins/messages.h
> +++ b/plugins/messages.h
> @@ -169,18 +169,17 @@ void messages_disconnect(void *session);
>   * value is used to set the error code in OBEX response.
>   ******************************************************************************/
>
> -/* Registers for messaging events notifications.
> +/* Registers Message Client for receiving message event reports.
>   *
>   * session: Backend session.
> - * send_event: Function that will be called to indicate a new event.
> - *
> - * To unregister currently registered notifications, call this with send_event
> - * set to NULL.
> + * address: Remote device address that request notification registration.
> + * status: To indicate message notification registraton status
> + * user_data: User data if any to be sent.
>   */
> -int messages_set_notification_registration(void *session,
> -               void (*send_event)(void *session,
> -                       const struct messages_event *event, void *user_data),
> -               void *user_data);
> +
> +int messages_set_notification_registration(void *session, char *address,
> +                                               uint8_t status,
> +                                               void *user_data);
>
>  /* Changes current directory.
>   *
> --
> 1.7.9.5


The plan is to merge client with server so we don't have to call each
other daemon to connect the notification service.


-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: [RFC, PATCH] hid-ps3remote: handle multiple keypresses for joypad buttons
From: David Dillow @ 2012-09-25  2:13 UTC (permalink / raw)
  To: Antonio Ospite
  Cc: linux-bluetooth, David Herrmann, Luiz Augusto von Dentz,
	Bastien Nocera, linux-input, jkosina
In-Reply-To: <1348495002.7637.4.camel@obelisk.thedillows.org>

On Mon, 2012-09-24 at 09:56 -0400, David Dillow wrote:
> On Mon, 2012-09-24 at 13:25 +0200, Antonio Ospite wrote:
> > In order to make this work I have to put joypad buttons only in one of
> > the key maps, I don't know if that is compatible with the Harmony
> > adapter.
> 
> I suspect it is, but I'll try to test later tonight. Feel free to merge
> my patch and yours and push it upstream under your name/copyright; I'm
> not attached to it.

Yep, this works with the Harmony.

I think the logic you are using may result in some combinations being
missed -- say Triangle + Play -- but I'm not sure how much it matters. I
can rework the first version (building a custom report based on the
funky rules of coding) in the next few days, or you can push your
version if you'd like. Or perhaps a middle way, that erases the buttons
reported in the bitmap from the byte array, but otherwise keeps track of
the last press in that area to avoid weirdness when the user presses a
button combo that cannot be reported due to the HW limitations.

Dave


^ permalink raw reply

* [PATCH v3 BlueZ 4/4] attrib: Remove opcode parameter from g_attrib_send()
From: Vinicius Costa Gomes @ 2012-09-24 22:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1348526019-28402-1-git-send-email-vinicius.gomes@openbossa.org>

In all uses of g_attrib_send() the opcode of the command/event is
already clear because of the att.h functions used to build the ATT
PDU.
---
 attrib/client.c                    |  3 +-
 attrib/gatt.c                      | 56 ++++++++++++++++----------------------
 attrib/gattrib.c                   |  9 ++++--
 attrib/gattrib.h                   |  6 ++--
 attrib/gatttool.c                  |  2 +-
 attrib/interactive.c               |  2 +-
 profiles/gatt/gas.c                |  2 +-
 profiles/thermometer/thermometer.c |  3 +-
 src/attrib-server.c                |  3 +-
 9 files changed, 39 insertions(+), 47 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 2423fad..a1cc2f3 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -365,8 +365,7 @@ static void events_handler(const uint8_t *pdu, uint16_t len,
 	case ATT_OP_HANDLE_IND:
 		opdu = g_attrib_get_buffer(gatt->attrib, &plen);
 		olen = enc_confirmation(opdu, plen);
-		g_attrib_send(gatt->attrib, 0, opdu[0], opdu, olen,
-						NULL, NULL, NULL);
+		g_attrib_send(gatt->attrib, 0, opdu, olen, NULL, NULL, NULL);
 	case ATT_OP_HANDLE_NOTIFY:
 		if (characteristic_set_value(chr, &pdu[3], len - 3) < 0)
 			DBG("Can't change Characteristic 0x%02x", handle);
diff --git a/attrib/gatt.c b/attrib/gatt.c
index 902ac23..e6db227 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -176,8 +176,7 @@ static void primary_by_uuid_cb(guint8 status, const guint8 *ipdu,
 	if (oplen == 0)
 		goto done;
 
-	g_attrib_send(dp->attrib, 0, buf[0], buf, oplen, primary_by_uuid_cb,
-								dp, NULL);
+	g_attrib_send(dp->attrib, 0, buf, oplen, primary_by_uuid_cb, dp, NULL);
 	return;
 
 done:
@@ -242,7 +241,7 @@ static void primary_all_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 		guint16 oplen = encode_discover_primary(end + 1, 0xffff, NULL,
 								buf, buflen);
 
-		g_attrib_send(dp->attrib, 0, buf[0], buf, oplen, primary_all_cb,
+		g_attrib_send(dp->attrib, 0, buf, oplen, primary_all_cb,
 								dp, NULL);
 
 		return;
@@ -280,7 +279,7 @@ guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 	} else
 		cb = primary_all_cb;
 
-	return g_attrib_send(attrib, 0, buf[0], buf, plen, cb, dp, NULL);
+	return g_attrib_send(attrib, 0, buf, plen, cb, dp, NULL);
 }
 
 static void resolve_included_uuid_cb(uint8_t status, const uint8_t *pdu,
@@ -331,8 +330,8 @@ static guint resolve_included_uuid(struct find_included *fi,
 	resolve->fi = find_included_ref(fi);
 	resolve->included = incl;
 
-	return g_attrib_send(fi->attrib, 0, buf[0], buf, oplen,
-					resolve_included_uuid_cb, resolve, NULL);
+	return g_attrib_send(fi->attrib, 0, buf, oplen,
+				resolve_included_uuid_cb, resolve, NULL);
 }
 
 static struct gatt_included *included_from_buf(const uint8_t *buf, gsize buflen)
@@ -370,8 +369,8 @@ static guint find_included(struct find_included *fi, uint16_t start)
 
 	find_included_ref(fi);
 
-	return g_attrib_send(fi->attrib, 0, buf[0], buf, oplen,
-						find_included_cb, fi, NULL);
+	return g_attrib_send(fi->attrib, 0, buf, oplen, find_included_cb,
+								fi, NULL);
 }
 
 static void find_included_cb(uint8_t status, const uint8_t *pdu, uint16_t len,
@@ -508,8 +507,8 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 		if (oplen == 0)
 			return;
 
-		g_attrib_send(dc->attrib, 0, buf[0], buf, oplen,
-						char_discovered_cb, dc, NULL);
+		g_attrib_send(dc->attrib, 0, buf, oplen, char_discovered_cb,
+								dc, NULL);
 
 		return;
 	}
@@ -547,7 +546,7 @@ guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
 	dc->end = end;
 	dc->uuid = g_memdup(uuid, sizeof(bt_uuid_t));
 
-	return g_attrib_send(attrib, 0, buf[0], buf, plen, char_discovered_cb,
+	return g_attrib_send(attrib, 0, buf, plen, char_discovered_cb,
 								dc, NULL);
 }
 
@@ -563,8 +562,7 @@ guint gatt_read_char_by_uuid(GAttrib *attrib, uint16_t start, uint16_t end,
 	if (plen == 0)
 		return 0;
 
-	return g_attrib_send(attrib, 0, ATT_OP_READ_BY_TYPE_REQ,
-					buf, plen, func, user_data, NULL);
+	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
 }
 
 struct read_long_data {
@@ -623,8 +621,7 @@ static void read_blob_helper(guint8 status, const guint8 *rpdu, guint16 rlen,
 
 	plen = enc_read_blob_req(long_read->handle, long_read->size - 1,
 								buf, buflen);
-	id = g_attrib_send(long_read->attrib, long_read->id,
-				ATT_OP_READ_BLOB_REQ, buf, plen,
+	id = g_attrib_send(long_read->attrib, long_read->id, buf, plen,
 				read_blob_helper, long_read, read_long_destroy);
 
 	if (id != 0) {
@@ -660,9 +657,8 @@ static void read_char_helper(guint8 status, const guint8 *rpdu,
 	long_read->size = rlen;
 
 	plen = enc_read_blob_req(long_read->handle, rlen - 1, buf, buflen);
-	id = g_attrib_send(long_read->attrib, long_read->id,
-			ATT_OP_READ_BLOB_REQ, buf, plen, read_blob_helper,
-			long_read, read_long_destroy);
+	id = g_attrib_send(long_read->attrib, long_read->id, buf, plen,
+			read_blob_helper, long_read, read_long_destroy);
 
 	if (id != 0) {
 		g_atomic_int_inc(&long_read->ref);
@@ -698,12 +694,12 @@ guint gatt_read_char(GAttrib *attrib, uint16_t handle, uint16_t offset,
 	if (offset > 0) {
 		plen = enc_read_blob_req(long_read->handle, offset, buf,
 									buflen);
-		id = g_attrib_send(attrib, 0, ATT_OP_READ_BLOB_REQ, buf, plen,
-				read_blob_helper, long_read, read_long_destroy);
+		id = g_attrib_send(attrib, 0, buf, plen, read_blob_helper,
+						long_read, read_long_destroy);
 	} else {
 		plen = enc_read_req(handle, buf, buflen);
-		id = g_attrib_send(attrib, 0, ATT_OP_READ_REQ, buf, plen,
-				read_char_helper, long_read, read_long_destroy);
+		id = g_attrib_send(attrib, 0, buf, plen, read_char_helper,
+						long_read, read_long_destroy);
 	}
 
 	if (id == 0)
@@ -738,8 +734,7 @@ static guint execute_write(GAttrib *attrib, uint8_t flags,
 	if (plen == 0)
 		return 0;
 
-	return g_attrib_send(attrib, 0, buf[0], buf, plen, func, user_data,
-									NULL);
+	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
 }
 
 static guint prepare_write(GAttrib *attrib, uint16_t handle, uint16_t offset,
@@ -788,7 +783,7 @@ static guint prepare_write(GAttrib *attrib, uint16_t handle, uint16_t offset,
 	if (plen == 0)
 		return 0;
 
-	return g_attrib_send(attrib, 0, buf[0], buf, plen, prepare_write_cb,
+	return g_attrib_send(attrib, 0, buf, plen, prepare_write_cb,
 							user_data, NULL);
 }
 
@@ -812,7 +807,7 @@ guint gatt_write_char(GAttrib *attrib, uint16_t handle, uint8_t *value,
 			plen = enc_write_cmd(handle, value, vlen, buf,
 								buflen);
 
-		return g_attrib_send(attrib, 0, buf[0], buf, plen, func,
+		return g_attrib_send(attrib, 0, buf, plen, func,
 							user_data, NULL);
 	}
 
@@ -841,8 +836,7 @@ guint gatt_exchange_mtu(GAttrib *attrib, uint16_t mtu, GAttribResultFunc func,
 
 	buf = g_attrib_get_buffer(attrib, &buflen);
 	plen = enc_mtu_req(mtu, buf, buflen);
-	return g_attrib_send(attrib, 0, ATT_OP_MTU_REQ, buf, plen, func,
-							user_data, NULL);
+	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
 }
 
 guint gatt_find_info(GAttrib *attrib, uint16_t start, uint16_t end,
@@ -857,8 +851,7 @@ guint gatt_find_info(GAttrib *attrib, uint16_t start, uint16_t end,
 	if (plen == 0)
 		return 0;
 
-	return g_attrib_send(attrib, 0, ATT_OP_FIND_INFO_REQ, buf, plen, func,
-							user_data, NULL);
+	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
 }
 
 guint gatt_write_cmd(GAttrib *attrib, uint16_t handle, uint8_t *value, int vlen,
@@ -870,8 +863,7 @@ guint gatt_write_cmd(GAttrib *attrib, uint16_t handle, uint8_t *value, int vlen,
 
 	buf = g_attrib_get_buffer(attrib, &buflen);
 	plen = enc_write_cmd(handle, value, vlen, buf, buflen);
-	return g_attrib_send(attrib, 0, ATT_OP_WRITE_CMD, buf, plen, NULL,
-							user_data, notify);
+	return g_attrib_send(attrib, 0, buf, plen, NULL, user_data, notify);
 }
 
 static sdp_data_t *proto_seq_find(sdp_list_t *proto_list)
diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index 108d1d3..6f6942f 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -472,12 +472,13 @@ GAttrib *g_attrib_new(GIOChannel *io)
 	return g_attrib_ref(attrib);
 }
 
-guint g_attrib_send(GAttrib *attrib, guint id, guint8 opcode,
-			const guint8 *pdu, guint16 len, GAttribResultFunc func,
-			gpointer user_data, GDestroyNotify notify)
+guint g_attrib_send(GAttrib *attrib, guint id, const guint8 *pdu, guint16 len,
+			GAttribResultFunc func, gpointer user_data,
+			GDestroyNotify notify)
 {
 	struct command *c;
 	GQueue *queue;
+	uint8_t opcode;
 
 	if (attrib->stale)
 		return 0;
@@ -486,6 +487,8 @@ guint g_attrib_send(GAttrib *attrib, guint id, guint8 opcode,
 	if (c == NULL)
 		return 0;
 
+	opcode = pdu[0];
+
 	c->opcode = opcode;
 	c->expected = opcode2expected(opcode);
 	c->pdu = g_malloc(len);
diff --git a/attrib/gattrib.h b/attrib/gattrib.h
index bcff039..bca966f 100644
--- a/attrib/gattrib.h
+++ b/attrib/gattrib.h
@@ -50,9 +50,9 @@ GIOChannel *g_attrib_get_channel(GAttrib *attrib);
 gboolean g_attrib_set_destroy_function(GAttrib *attrib,
 		GDestroyNotify destroy, gpointer user_data);
 
-guint g_attrib_send(GAttrib *attrib, guint id, guint8 opcode,
-			const guint8 *pdu, guint16 len, GAttribResultFunc func,
-			gpointer user_data, GDestroyNotify notify);
+guint g_attrib_send(GAttrib *attrib, guint id, const guint8 *pdu, guint16 len,
+			GAttribResultFunc func, gpointer user_data,
+			GDestroyNotify notify);
 
 gboolean g_attrib_cancel(GAttrib *attrib, guint id);
 gboolean g_attrib_cancel_all(GAttrib *attrib);
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 416bb71..dea1fc4 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -105,7 +105,7 @@ static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
 	olen = enc_confirmation(opdu, plen);
 
 	if (olen > 0)
-		g_attrib_send(attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL);
+		g_attrib_send(attrib, 0, opdu, olen, NULL, NULL, NULL);
 }
 
 static gboolean listen_start(gpointer user_data)
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 9f1192e..1b0b9cf 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -135,7 +135,7 @@ static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
 	olen = enc_confirmation(opdu, plen);
 
 	if (olen > 0)
-		g_attrib_send(attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL);
+		g_attrib_send(attrib, 0, opdu, olen, NULL, NULL, NULL);
 }
 
 static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index 28d7fbf..4d8797e 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -150,7 +150,7 @@ static void indication_cb(const uint8_t *pdu, uint16_t len, gpointer user_data)
 	/* Confirming indication received */
 	opdu = g_attrib_get_buffer(gas->attrib, &plen);
 	olen = enc_confirmation(opdu, plen);
-	g_attrib_send(gas->attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL);
+	g_attrib_send(gas->attrib, 0, opdu, olen, NULL, NULL, NULL);
 
 	if (gas->changed.start == start && gas->changed.end == end)
 		return;
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 77dcb26..e9f61b1 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -1167,8 +1167,7 @@ static void ind_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
 	olen = enc_confirmation(opdu, plen);
 
 	if (olen > 0)
-		g_attrib_send(t->attrib, 0, opdu[0], opdu, olen, NULL, NULL,
-									NULL);
+		g_attrib_send(t->attrib, 0, opdu, olen, NULL, NULL, NULL);
 }
 
 static void notif_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 9b03e54..afe5e48 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -1031,8 +1031,7 @@ done:
 		length = enc_error_resp(ipdu[0], 0x0000, status, opdu,
 								channel->mtu);
 
-	g_attrib_send(channel->attrib, 0, opdu[0], opdu, length,
-							NULL, NULL, NULL);
+	g_attrib_send(channel->attrib, 0, opdu, length, NULL, NULL, NULL);
 }
 
 guint attrib_channel_attach(GAttrib *attrib)
-- 
1.7.12.1


^ permalink raw reply related

* [PATCH v3 BlueZ 3/4] core: Add support for included services
From: Vinicius Costa Gomes @ 2012-09-24 22:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1348526019-28402-1-git-send-email-vinicius.gomes@openbossa.org>

Soon after the primary service discovery is complete, we do a included
services discovery for all found services and add each included service
to the 'services' list so they can be probe()'d as a normal profile.

This will also make these services to appear on the D-Bus object tree.
---
 src/device.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 96 insertions(+), 13 deletions(-)

diff --git a/src/device.c b/src/device.c
index aa3a607..932f1f9 100644
--- a/src/device.c
+++ b/src/device.c
@@ -104,6 +104,12 @@ struct browse_req {
 	guint listener_id;
 };
 
+struct included_search {
+	struct browse_req *req;
+	GSList *services;
+	GSList *current;
+};
+
 struct attio_data {
 	guint id;
 	attio_connect_cb cfunc;
@@ -1822,21 +1828,10 @@ static void device_unregister_services(struct btd_device *device)
 	device->services = NULL;
 }
 
-static void primary_cb(GSList *services, guint8 status, gpointer user_data)
+static void register_all_services(struct browse_req *req, GSList *services)
 {
-	struct browse_req *req = user_data;
 	struct btd_device *device = req->device;
 
-	if (status) {
-		if (req->msg) {
-			DBusMessage *reply;
-			reply = btd_error_failed(req->msg,
-							att_ecode2str(status));
-			g_dbus_send_message(btd_get_dbus_connection(), reply);
-		}
-		goto done;
-	}
-
 	device_set_temporary(device, FALSE);
 
 	if (device->services)
@@ -1861,11 +1856,99 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 
 	store_services(device);
 
-done:
 	device->browse = NULL;
 	browse_request_free(req);
 }
 
+static int service_by_range_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct gatt_primary *prim = a;
+	const struct att_range *range = b;
+
+	return memcmp(&prim->range, range, sizeof(*range));
+}
+
+static void find_included_cb(GSList *includes, uint8_t status,
+						gpointer user_data)
+{
+	struct included_search *search = user_data;
+	struct btd_device *device = search->req->device;
+	struct gatt_primary *prim;
+	GSList *l;
+
+	if (includes == NULL)
+		goto done;
+
+	for (l = includes; l; l = l->next) {
+		struct gatt_included *incl = l->data;
+
+		if (g_slist_find_custom(search->services, &incl->range,
+						service_by_range_cmp))
+			continue;
+
+		prim = g_new0(struct gatt_primary, 1);
+		memcpy(prim->uuid, incl->uuid, sizeof(prim->uuid));
+		memcpy(&prim->range, &incl->range, sizeof(prim->range));
+
+		search->services = g_slist_append(search->services, prim);
+	}
+
+done:
+	search->current = search->current->next;
+	if (search->current == NULL) {
+		register_all_services(search->req, search->services);
+		g_slist_free(search->services);
+		g_free(search);
+		return;
+	}
+
+	prim = search->current->data;
+	gatt_find_included(device->attrib, prim->range.start, prim->range.end,
+					find_included_cb, search);
+}
+
+static void find_included_services(struct browse_req *req, GSList *services)
+{
+	struct btd_device *device = req->device;
+	struct included_search *search;
+	struct gatt_primary *prim;
+
+	if (services == NULL)
+		return;
+
+	search = g_new0(struct included_search, 1);
+	search->req = req;
+	search->services = g_slist_copy(services);
+	search->current = search->services;
+
+	prim = search->current->data;
+	gatt_find_included(device->attrib, prim->range.start, prim->range.end,
+					find_included_cb, search);
+
+}
+
+static void primary_cb(GSList *services, guint8 status, gpointer user_data)
+{
+	struct browse_req *req = user_data;
+
+	if (status) {
+		struct btd_device *device = req->device;
+
+		if (req->msg) {
+			DBusMessage *reply;
+			reply = btd_error_failed(req->msg,
+							att_ecode2str(status));
+			g_dbus_send_message(btd_get_dbus_connection(), reply);
+		}
+
+		device->browse = NULL;
+		browse_request_free(req);
+		return;
+	}
+
+	find_included_services(req, services);
+}
+
 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 {
 	struct att_callbacks *attcb = user_data;
-- 
1.7.12.1


^ permalink raw reply related

* [PATCH v3 BlueZ 2/4] gatttool: Add "included" command
From: Vinicius Costa Gomes @ 2012-09-24 22:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jefferson Delfes
In-Reply-To: <1348526019-28402-1-git-send-email-vinicius.gomes@openbossa.org>

From: Jefferson Delfes <jefferson.delfes@openbossa.org>

New command to find included services in interactive mode.
---
 attrib/interactive.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index 38ac30f..9f1192e 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -211,6 +211,34 @@ static void primary_by_uuid_cb(GSList *ranges, guint8 status,
 	rl_forced_update_display();
 }
 
+static void included_cb(GSList *includes, guint8 status, gpointer user_data)
+{
+	GSList *l;
+
+	if (status) {
+		printf("Find included services failed: %s\n",
+							att_ecode2str(status));
+		goto done;
+	}
+
+	if (includes == NULL) {
+		printf("No included services found for this range\n");
+		goto done;
+	}
+
+	printf("\n");
+	for (l = includes; l; l = l->next) {
+		struct gatt_included *incl = l->data;
+		printf("handle: 0x%04x, start handle: 0x%04x, "
+						"end handle: 0x%04x uuid: %s\n",
+						incl->handle, incl->range.start,
+						incl->range.end, incl->uuid);
+	}
+
+done:
+	rl_forced_update_display();
+}
+
 static void char_cb(GSList *characteristics, guint8 status, gpointer user_data)
 {
 	GSList *l;
@@ -431,6 +459,36 @@ static int strtohandle(const char *src)
 	return dst;
 }
 
+static void cmd_included(int argcp, char **argvp)
+{
+	int start = 0x0001;
+	int end = 0xffff;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (argcp > 1) {
+		start = strtohandle(argvp[1]);
+		if (start < 0) {
+			printf("Invalid start handle: %s\n", argvp[1]);
+			return;
+		}
+		end = start;
+	}
+
+	if (argcp > 2) {
+		end = strtohandle(argvp[2]);
+		if (end < 0) {
+			printf("Invalid end handle: %s\n", argvp[2]);
+			return;
+		}
+	}
+
+	gatt_find_included(attrib, start, end, included_cb, NULL);
+}
+
 static void cmd_char(int argcp, char **argvp)
 {
 	int start = 0x0001;
@@ -755,6 +813,8 @@ static struct {
 		"Disconnect from a remote device" },
 	{ "primary",		cmd_primary,	"[UUID]",
 		"Primary Service Discovery" },
+	{ "included",		cmd_included,	"[start hnd [end hnd]]",
+		"Find Included Services" },
 	{ "characteristics",	cmd_char,	"[start hnd [end hnd [UUID]]]",
 		"Characteristics Discovery" },
 	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
-- 
1.7.12.1


^ permalink raw reply related

* [PATCH v3 BlueZ 1/4] gatt: Add support for find included services
From: Vinicius Costa Gomes @ 2012-09-24 22:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes
In-Reply-To: <1348526019-28402-1-git-send-email-vinicius.gomes@openbossa.org>

Some services like HID over LE can reference another service using
included services.

See Vol 3, Part G, section 2.6.3 of Core specification for more
details.
---
 attrib/gatt.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 attrib/gatt.h |   9 +++
 2 files changed, 203 insertions(+)

diff --git a/attrib/gatt.c b/attrib/gatt.c
index 6880e2d..902ac23 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -45,6 +45,21 @@ struct discover_primary {
 	void *user_data;
 };
 
+struct find_included {
+	GAttrib		*attrib;
+	int		refs;
+	int		err;
+	uint16_t	end_handle;
+	GSList		*includes;
+	gatt_cb_t	cb;
+	void		*user_data;
+};
+
+struct included_uuid_resolve {
+	struct find_included *fi;
+	struct gatt_included *included;
+};
+
 struct discover_char {
 	GAttrib *attrib;
 	bt_uuid_t *uuid;
@@ -61,6 +76,26 @@ static void discover_primary_free(struct discover_primary *dp)
 	g_free(dp);
 }
 
+static struct find_included *find_included_ref(struct find_included *fi)
+{
+	g_atomic_int_inc(&fi->refs);
+
+	return fi;
+}
+
+static void find_included_unref(struct find_included *fi)
+{
+	if (g_atomic_int_dec_and_test(&fi->refs) == FALSE)
+		return;
+
+	fi->cb(fi->includes, fi->err, fi->user_data);
+
+	g_slist_free_full(fi->includes, g_free);
+	g_attrib_unref(fi->attrib);
+	g_free(fi);
+}
+
+
 static void discover_char_free(struct discover_char *dc)
 {
 	g_slist_free_full(dc->characteristics, g_free);
@@ -248,6 +283,165 @@ guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 	return g_attrib_send(attrib, 0, buf[0], buf, plen, cb, dp, NULL);
 }
 
+static void resolve_included_uuid_cb(uint8_t status, const uint8_t *pdu,
+					uint16_t len, gpointer user_data)
+{
+	struct included_uuid_resolve *resolve = user_data;
+	struct find_included *fi = resolve->fi;
+	struct gatt_included *incl = resolve->included;
+	bt_uuid_t uuid;
+	unsigned int err = status;
+	size_t buflen;
+	uint8_t *buf;
+
+	if (err)
+		goto done;
+
+	buf = g_attrib_get_buffer(fi->attrib, &buflen);
+	if (dec_read_resp(pdu, len, buf, buflen) != 16) {
+		err = ATT_ECODE_IO;
+		goto done;
+	}
+
+	uuid = att_get_uuid128(buf);
+	bt_uuid_to_string(&uuid, incl->uuid, sizeof(incl->uuid));
+	fi->includes = g_slist_append(fi->includes, incl);
+
+done:
+	if (err)
+		g_free(incl);
+
+	if (fi->err == 0)
+		fi->err = err;
+
+	find_included_unref(fi);
+
+	g_free(resolve);
+}
+
+static guint resolve_included_uuid(struct find_included *fi,
+					struct gatt_included *incl)
+{
+	size_t buflen;
+	uint8_t *buf = g_attrib_get_buffer(fi->attrib, &buflen);
+	guint16 oplen = enc_read_req(incl->range.start, buf, buflen);
+	struct included_uuid_resolve *resolve;
+
+	resolve = g_new0(struct included_uuid_resolve, 1);
+	resolve->fi = find_included_ref(fi);
+	resolve->included = incl;
+
+	return g_attrib_send(fi->attrib, 0, buf[0], buf, oplen,
+					resolve_included_uuid_cb, resolve, NULL);
+}
+
+static struct gatt_included *included_from_buf(const uint8_t *buf, gsize buflen)
+{
+	struct gatt_included *incl = g_new0(struct gatt_included, 1);
+
+	incl->handle = att_get_u16(&buf[0]);
+	incl->range.start = att_get_u16(&buf[2]);
+	incl->range.end = att_get_u16(&buf[4]);
+
+	if (buflen == 8) {
+		bt_uuid_t uuid128;
+		bt_uuid_t uuid16 = att_get_uuid16(&buf[6]);
+
+		bt_uuid_to_uuid128(&uuid16, &uuid128);
+		bt_uuid_to_string(&uuid128, incl->uuid, sizeof(incl->uuid));
+	}
+
+	return incl;
+}
+
+static void find_included_cb(uint8_t status, const uint8_t *pdu, uint16_t len,
+							gpointer user_data);
+
+static guint find_included(struct find_included *fi, uint16_t start)
+{
+	bt_uuid_t uuid;
+	size_t buflen;
+	uint8_t *buf = g_attrib_get_buffer(fi->attrib, &buflen);
+	guint16 oplen;
+
+	bt_uuid16_create(&uuid, GATT_INCLUDE_UUID);
+	oplen = enc_read_by_type_req(start, fi->end_handle, &uuid,
+							buf, buflen);
+
+	find_included_ref(fi);
+
+	return g_attrib_send(fi->attrib, 0, buf[0], buf, oplen,
+						find_included_cb, fi, NULL);
+}
+
+static void find_included_cb(uint8_t status, const uint8_t *pdu, uint16_t len,
+							gpointer user_data)
+{
+	struct find_included *fi = user_data;
+	uint16_t last_handle = fi->end_handle;
+	unsigned int err = status;
+	struct att_data_list *list;
+	int i;
+
+	if (err == ATT_ECODE_ATTR_NOT_FOUND)
+		err = 0;
+
+	if (status)
+		goto done;
+
+	list = dec_read_by_type_resp(pdu, len);
+	if (list == NULL) {
+		err = ATT_ECODE_IO;
+		goto done;
+	}
+
+	if (list->len != 6 && list->len != 8) {
+		err = ATT_ECODE_IO;
+		att_data_list_free(list);
+		goto done;
+	}
+
+	for (i = 0; i < list->num; i++) {
+		struct gatt_included *incl;
+
+		incl = included_from_buf(list->data[i], list->len);
+		last_handle = incl->handle;
+
+		/* 128 bit UUID, needs resolving */
+		if (list->len == 6) {
+			resolve_included_uuid(fi, incl);
+			continue;
+		}
+
+		fi->includes = g_slist_append(fi->includes, incl);
+	}
+
+	att_data_list_free(list);
+
+	if (last_handle < fi->end_handle)
+		find_included(fi, last_handle + 1);
+
+done:
+	if (fi->err == 0)
+		fi->err = err;
+
+	find_included_unref(fi);
+}
+
+unsigned int gatt_find_included(GAttrib *attrib, uint16_t start, uint16_t end,
+					gatt_cb_t func, gpointer user_data)
+{
+	struct find_included *fi;
+
+	fi = g_new0(struct find_included, 1);
+	fi->attrib = g_attrib_ref(attrib);
+	fi->end_handle = end;
+	fi->cb = func;
+	fi->user_data = user_data;
+
+	return find_included(fi, start);
+}
+
 static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 							gpointer user_data)
 {
diff --git a/attrib/gatt.h b/attrib/gatt.h
index 6bb6f0f..2897482 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -61,6 +61,12 @@ struct gatt_primary {
 	struct att_range range;
 };
 
+struct gatt_included {
+	char uuid[MAX_LEN_UUID_STR + 1];
+	uint16_t handle;
+	struct att_range range;
+};
+
 struct gatt_char {
 	char uuid[MAX_LEN_UUID_STR + 1];
 	uint16_t handle;
@@ -71,6 +77,9 @@ struct gatt_char {
 guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 							gpointer user_data);
 
+unsigned int gatt_find_included(GAttrib *attrib, uint16_t start, uint16_t end,
+					gatt_cb_t func, gpointer user_data);
+
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
 					bt_uuid_t *uuid, gatt_cb_t func,
 					gpointer user_data);
-- 
1.7.12.1


^ permalink raw reply related

* [PATCH v3 BlueZ 0/4] Support for GATT Find Included
From: Vinicius Costa Gomes @ 2012-09-24 22:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

Hi,

Changes from v2:
 - Rebased against latest git tree;

Changes from v1:
 - Fixed problems found during PTS tests;

 - Added a reference count for requests that are running in "parallel"
   (if a included service has a 128 bit UUID, it needs to make an
   aditional request to resolve this included service);

--

Jefferson Delfes (1):
  gatttool: Add "included" command

Vinicius Costa Gomes (3):
  gatt: Add support for find included services
  core: Add support for included services
  attrib: Remove opcode parameter from g_attrib_send()

 attrib/client.c                    |   3 +-
 attrib/gatt.c                      | 242 ++++++++++++++++++++++++++++++++-----
 attrib/gatt.h                      |   9 ++
 attrib/gattrib.c                   |   9 +-
 attrib/gattrib.h                   |   6 +-
 attrib/gatttool.c                  |   2 +-
 attrib/interactive.c               |  62 +++++++++-
 profiles/gatt/gas.c                |   2 +-
 profiles/thermometer/thermometer.c |   3 +-
 src/attrib-server.c                |   3 +-
 src/device.c                       | 109 +++++++++++++++--
 11 files changed, 394 insertions(+), 56 deletions(-)

-- 
1.7.12.1


^ permalink raw reply

* Re: pull request: bluetooth-next 2012-09-18
From: Gustavo Padovan @ 2012-09-24 22:31 UTC (permalink / raw)
  To: John W. Linville
  Cc: Luis R. Rodriguez, linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <20120924195422.GF32351@tuxdriver.com>

* John W. Linville <linville@tuxdriver.com> [2012-09-24 15:54:22 -0400]:

> On Mon, Sep 24, 2012 at 03:46:22PM -0300, Gustavo Padovan wrote:
> > * Luis R. Rodriguez <mcgrof@do-not-panic.com> [2012-09-21 18:06:42 -0700]:
> > 
> > > On Tue, Sep 18, 2012 at 6:31 PM, Gustavo Padovan <gustavo@padovan.org> wrote:
> > > 
> > > > Johan Hedberg (2):
> > > >       Bluetooth: mgmt: Implement support for passkey notification
> > > 
> > > Too late now... but why did we allow this a stable fix? I get its a
> > > feature that is important and likely overlooked / someone had a brain
> > > fart, but from what I gather this is not on v3.5.4 and yet may make it
> > > to v3.5.5. At least for backporting this was a bitch:
> 
> <snip>
> 
> > Yes, this patch is wrongly marked as stable, it is not even going to 3.5. I'm
> > just removing the tag from it and resending the pull request to John.
> 
> Hmmm...well, I already pulled it, and I just pushed it out.  Can we live with it?

Yes, that would be ok for me.

	Gustavo

^ permalink raw reply

* Re: [RFC v0] device: Add DiscoveryComplete signal
From: Luiz Augusto von Dentz @ 2012-09-24 20:10 UTC (permalink / raw)
  To: Chen Ganir; +Cc: Mikel Astiz, linux-bluetooth, Mikel Astiz
In-Reply-To: <506044CD.7070209@ti.com>

Hi Mikel, Chen,

On Mon, Sep 24, 2012 at 2:32 PM, Chen Ganir <chen.ganir@ti.com> wrote:
> Mikel,
>
>
> On 09/24/2012 01:19 PM, Mikel Astiz wrote:
>>
>> From: Mikel Astiz <mikel.astiz@bmw-carit.de>
>>
>> The D-Bus API has to report when the UUID property has been fully
>> populated, once the service discovery has been finished as part of the
>> pairing process. This allows UIs to show the device only after its
>> services are known, avoiding transitional states.
>> ---
>
> We have the PropertyChanged signal, which is triggered wach time the
> search_cb is called (device.c). Why do you need to create a new signal,
> instead of using this already existing event, and send PropertyChanged on
> UUIDS with the peer device list of UUID's only when the list is complete and
> not on every SDP record found ? This way, you can keep the existing
> implementations working, and you can also add new functionality based on the
> fact that you only receive one instance of this event ?

The Properties interfaces will have grouping support:
http://dbus.freedesktop.org/doc/dbus-specification.html#standard-interfaces-properties

Not only that, but the UI will also be able to listen for the device
object interfaces once we have the ObjectManager integrated, which
should also support grouping the interfaces which is probably a more
correct way to determine what are supported.

-- 
Luiz Augusto von Dentz

^ permalink raw reply

* Re: pull request: bluetooth-next 2012-09-18
From: John W. Linville @ 2012-09-24 19:54 UTC (permalink / raw)
  To: Gustavo Padovan, Luis R. Rodriguez, linux-wireless,
	linux-bluetooth, linux-kernel
In-Reply-To: <20120924184622.GA7922@joana>

On Mon, Sep 24, 2012 at 03:46:22PM -0300, Gustavo Padovan wrote:
> * Luis R. Rodriguez <mcgrof@do-not-panic.com> [2012-09-21 18:06:42 -0700]:
> 
> > On Tue, Sep 18, 2012 at 6:31 PM, Gustavo Padovan <gustavo@padovan.org> wrote:
> > 
> > > Johan Hedberg (2):
> > >       Bluetooth: mgmt: Implement support for passkey notification
> > 
> > Too late now... but why did we allow this a stable fix? I get its a
> > feature that is important and likely overlooked / someone had a brain
> > fart, but from what I gather this is not on v3.5.4 and yet may make it
> > to v3.5.5. At least for backporting this was a bitch:

<snip>

> Yes, this patch is wrongly marked as stable, it is not even going to 3.5. I'm
> just removing the tag from it and resending the pull request to John.

Hmmm...well, I already pulled it, and I just pushed it out.  Can we live with it?

John
-- 
John W. Linville		Someday the world will need a hero, and you
linville@tuxdriver.com			might be all we have.  Be ready.

^ permalink raw reply

* Re: pull request: bluetooth-next 2012-09-18
From: Gustavo Padovan @ 2012-09-24 18:46 UTC (permalink / raw)
  To: Luis R. Rodriguez; +Cc: linville, linux-wireless, linux-bluetooth, linux-kernel
In-Reply-To: <CAB=NE6XKNSMeS3_uzcGsGBhcm6ZKtJwJ=DdAq_DoWmKTXQvV=Q@mail.gmail.com>

* Luis R. Rodriguez <mcgrof@do-not-panic.com> [2012-09-21 18:06:42 -0700]:

> On Tue, Sep 18, 2012 at 6:31 PM, Gustavo Padovan <gustavo@padovan.org> wrote:
> 
> > Johan Hedberg (2):
> >       Bluetooth: mgmt: Implement support for passkey notification
> 
> Too late now... but why did we allow this a stable fix? I get its a
> feature that is important and likely overlooked / someone had a brain
> fart, but from what I gather this is not on v3.5.4 and yet may make it
> to v3.5.5. At least for backporting this was a bitch:
> 
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3290:52:
> error: dereferencing pointer to incomplete type
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3294:6:
> error: ‘struct hci_conn’ has no member named ‘passkey_notify’
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3294:25:
> error: dereferencing pointer to incomplete type
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3295:6:
> error: ‘struct hci_conn’ has no member named ‘passkey_entered’
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3298:3:
> error: implicit declaration of function ‘mgmt_user_passkey_notify’
> [-Werror=implicit-function-declaration]
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3299:27:
> error: ‘struct hci_conn’ has no member named ‘passkey_notify’
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3300:11:
> error: ‘struct hci_conn’ has no member named ‘passkey_entered’
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:
> In function ‘hci_keypress_notify_evt’:
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3310:52:
> error: dereferencing pointer to incomplete type
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3314:12:
> error: dereferencing pointer to incomplete type
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3315:7:
> error: ‘HCI_KEYPRESS_STARTED’ undeclared (first use in this function)
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3315:7:
> note: each undeclared identifier is reported only once for each
> function it appears in
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3316:7:
> error: ‘struct hci_conn’ has no member named ‘passkey_entered’
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3319:7:
> error: ‘HCI_KEYPRESS_ENTERED’ undeclared (first use in this function)
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3320:7:
> error: ‘struct hci_conn’ has no member named ‘passkey_entered’
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3323:7:
> error: ‘HCI_KEYPRESS_ERASED’ undeclared (first use in this function)
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3324:7:
> error: ‘struct hci_conn’ has no member named ‘passkey_entered’
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3327:7:
> error: ‘HCI_KEYPRESS_CLEARED’ undeclared (first use in this function)
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3328:7:
> error: ‘struct hci_conn’ has no member named ‘passkey_entered’
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3331:7:
> error: ‘HCI_KEYPRESS_COMPLETED’ undeclared (first use in this
> function)
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3337:27:
> error: ‘struct hci_conn’ has no member named ‘passkey_notify’
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3338:11:
> error: ‘struct hci_conn’ has no member named ‘passkey_entered’
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:
> In function ‘hci_event_packet’:
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3701:7:
> error: ‘HCI_EV_USER_PASSKEY_NOTIFY’ undeclared (first use in this
> function)
> /home/mcgrof/staging/v3.5.4/compat-wireless-3.5.3-2-snpc/net/bluetooth/hci_event.c:3705:7:
> error: ‘HCI_EV_KEYPRESS_NOTIFY’ undeclared (first use in this
> function)
> 
> I'd much prefer to see things like these identified as 'important' but
> not 'fuck, this fixes that crash'. The fact that kernel maintainers
> may be anal about these sorts of patches is *good* for many reasons
> and figuring out a way to categorize, identify and allow users to reap
> benefits of backporting suck fixes / cherry picking a full solution is
> what something that should not interfere and hopefully be transparent
> to Linux upstream development.
> 
> Here's one way I dealt with these type of patches:
> 
> https://backports.wiki.kernel.org/index.php/Documentation/compat-drivers/additional-patches
> 
> If you look at the patch 'Bluetooth: mgmt: Implement support for
> passkey' its  a clear "feature" implementation, not a fucking fix.

Yes, this patch is wrongly marked as stable, it is not even going to 3.5. I'm
just removing the tag from it and resending the pull request to John.

	Gustavo

^ permalink raw reply

* [PATCH BlueZ 25/25] alert: Add support for unread alert notification
From: Anderson Lizardo @ 2012-09-24 18:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348509661-15967-1-git-send-email-anderson.lizardo@openbossa.org>

From: Eder Ruiz Maria <eder.ruiz@openbossa.org>

When UnreadAlert D-Bus method is called for a registered category
from Alert Notification Profile, The unread alert characteristic value
is notified.
---
 profiles/alert/server.c |   14 ++++++++++----
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 497891b..bc1af0b 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -96,6 +96,7 @@ enum notify_type {
 	NOTIFY_RINGER_SETTING = 0,
 	NOTIFY_ALERT_STATUS,
 	NOTIFY_NEW_ALERT,
+	NOTIFY_UNREAD_ALERT,
 	NOTIFY_SIZE,
 };
 
@@ -110,7 +111,6 @@ struct alert_adapter {
 	struct btd_adapter *adapter;
 	uint16_t supp_new_alert_cat_handle;
 	uint16_t supp_unread_alert_cat_handle;
-	uint16_t unread_alert_handle;
 	uint16_t hnd_ccc[NOTIFY_SIZE];
 	uint16_t hnd_value[NOTIFY_SIZE];
 };
@@ -352,6 +352,7 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
 				pdu, sizeof(pdu));
 		break;
 	case NOTIFY_NEW_ALERT:
+	case NOTIFY_UNREAD_ALERT:
 		len = enc_notification(al_adapter->hnd_value[type],
 					nd->value, nd->len, pdu, sizeof(pdu));
 		break;
@@ -645,8 +646,11 @@ static void update_unread_alert(gpointer data, gpointer user_data)
 	struct btd_adapter *adapter = al_adapter->adapter;
 	uint8_t *value = user_data;
 
-	attrib_db_update(adapter, al_adapter->unread_alert_handle, NULL, value,
-								2, NULL);
+	attrib_db_update(adapter,
+			al_adapter->hnd_value[NOTIFY_UNREAD_ALERT], NULL, value,
+			2, NULL);
+
+	notify_devices(al_adapter, NOTIFY_UNREAD_ALERT, value, 2);
 }
 
 static DBusMessage *unread_alert(DBusConnection *conn, DBusMessage *msg,
@@ -890,8 +894,10 @@ static void register_alert_notif_service(struct alert_adapter *al_adapter)
 			/* Unread Alert Status */
 			GATT_OPT_CHR_UUID, UNREAD_ALERT_CHR_UUID,
 			GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
+			GATT_OPT_CCC_GET_HANDLE,
+			&al_adapter->hnd_ccc[NOTIFY_UNREAD_ALERT],
 			GATT_OPT_CHR_VALUE_GET_HANDLE,
-			&al_adapter->unread_alert_handle,
+			&al_adapter->hnd_value[NOTIFY_UNREAD_ALERT],
 			/* Alert Notification Control Point */
 			GATT_OPT_CHR_UUID, ALERT_NOTIF_CP_CHR_UUID,
 			GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_WRITE,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH BlueZ 24/25] alert: Add support for new alert notification
From: Anderson Lizardo @ 2012-09-24 18:01 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348509661-15967-1-git-send-email-anderson.lizardo@openbossa.org>

From: Eder Ruiz Maria <eder.ruiz@openbossa.org>

When NewAlert D-Bus method is called for one category from Alert
Notification Profile, the new alert characteristic value is notified.
---
 profiles/alert/server.c |   17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index c531e02..497891b 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -95,6 +95,7 @@ enum {
 enum notify_type {
 	NOTIFY_RINGER_SETTING = 0,
 	NOTIFY_ALERT_STATUS,
+	NOTIFY_NEW_ALERT,
 	NOTIFY_SIZE,
 };
 
@@ -109,7 +110,6 @@ struct alert_adapter {
 	struct btd_adapter *adapter;
 	uint16_t supp_new_alert_cat_handle;
 	uint16_t supp_unread_alert_cat_handle;
-	uint16_t new_alert_handle;
 	uint16_t unread_alert_handle;
 	uint16_t hnd_ccc[NOTIFY_SIZE];
 	uint16_t hnd_value[NOTIFY_SIZE];
@@ -351,6 +351,10 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
 				&alert_status, sizeof(alert_status),
 				pdu, sizeof(pdu));
 		break;
+	case NOTIFY_NEW_ALERT:
+		len = enc_notification(al_adapter->hnd_value[type],
+					nd->value, nd->len, pdu, sizeof(pdu));
+		break;
 	default:
 		DBG("Unknown type, could not send notification");
 		goto end;
@@ -483,8 +487,11 @@ static void update_new_alert(gpointer data, gpointer user_data)
 	struct btd_adapter *adapter = al_adapter->adapter;
 	uint8_t *value = user_data;
 
-	attrib_db_update(adapter, al_adapter->new_alert_handle, NULL, &value[1],
-								value[0], NULL);
+        attrib_db_update(adapter,
+				al_adapter->hnd_value[NOTIFY_NEW_ALERT],
+				NULL, &value[1], value[0], NULL);
+
+	notify_devices(al_adapter, NOTIFY_NEW_ALERT, &value[1], value[0]);
 }
 
 static void update_phone_alerts(const char *category, const char *description)
@@ -869,8 +876,10 @@ static void register_alert_notif_service(struct alert_adapter *al_adapter)
 			/* New Alert */
 			GATT_OPT_CHR_UUID, NEW_ALERT_CHR_UUID,
 			GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_NOTIFY,
+			GATT_OPT_CCC_GET_HANDLE,
+			&al_adapter->hnd_ccc[NOTIFY_NEW_ALERT],
 			GATT_OPT_CHR_VALUE_GET_HANDLE,
-			&al_adapter->new_alert_handle,
+			&al_adapter->hnd_value[NOTIFY_NEW_ALERT],
 			/* Supported Unread Alert Category */
 			GATT_OPT_CHR_UUID, SUPP_UNREAD_ALERT_CAT_CHR_UUID,
 			GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_READ,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH BlueZ 23/25] alert: Add support for alert status notification
From: Anderson Lizardo @ 2012-09-24 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348509661-15967-1-git-send-email-anderson.lizardo@openbossa.org>

From: Eder Ruiz Maria <eder.ruiz@openbossa.org>

The notification is sent (to peer devices that have it enabled on the
CCC descriptor) every time the alert status characteristic value
changes.
---
 profiles/alert/server.c |   18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index d14f98e..c531e02 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -94,6 +94,7 @@ enum {
 
 enum notify_type {
 	NOTIFY_RINGER_SETTING = 0,
+	NOTIFY_ALERT_STATUS,
 	NOTIFY_SIZE,
 };
 
@@ -345,6 +346,11 @@ static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
 				&ringer_setting, sizeof(ringer_setting),
 				pdu, sizeof(pdu));
 		break;
+	case NOTIFY_ALERT_STATUS:
+		len = enc_notification(al_adapter->hnd_value[type],
+				&alert_status, sizeof(alert_status),
+				pdu, sizeof(pdu));
+		break;
 	default:
 		DBG("Unknown type, could not send notification");
 		goto end;
@@ -499,10 +505,14 @@ static void update_phone_alerts(const char *category, const char *description)
 
 	for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++) {
 		if (g_str_equal(pasp_categories[i], category)) {
-			if (g_str_equal(description, "active"))
+			if (g_str_equal(description, "active")) {
 				alert_status |= (1 << i);
-			else if (g_str_equal(description, "not active"))
+				pasp_notification(NOTIFY_ALERT_STATUS);
+			} else if (g_str_equal(description, "not active")) {
 				alert_status &= ~(1 << i);
+				pasp_notification(NOTIFY_ALERT_STATUS);
+			}
+			break;
 		}
 	}
 }
@@ -755,6 +765,10 @@ static void register_phone_alert_service(struct alert_adapter *al_adapter)
 							ATT_CHAR_PROPER_NOTIFY,
 			GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
 			alert_status_read, al_adapter->adapter,
+			GATT_OPT_CCC_GET_HANDLE,
+			&al_adapter->hnd_ccc[NOTIFY_ALERT_STATUS],
+			GATT_OPT_CHR_VALUE_GET_HANDLE,
+			&al_adapter->hnd_value[NOTIFY_ALERT_STATUS],
 			/* Ringer Control Point characteristic */
 			GATT_OPT_CHR_UUID, RINGER_CP_CHR_UUID,
 			GATT_OPT_CHR_PROPS, ATT_CHAR_PROPER_WRITE_WITHOUT_RESP,
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH BlueZ 22/25] alert: Add support for ringer setting notification
From: Anderson Lizardo @ 2012-09-24 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348509661-15967-1-git-send-email-anderson.lizardo@openbossa.org>

From: Eder Ruiz Maria <eder.ruiz@openbossa.org>

When the agent reports a ringer setting change, a ringer setting
notification is sent to the peer device (if notification is enabled).
---
 profiles/alert/server.c |  156 ++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 154 insertions(+), 2 deletions(-)

diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 58d7c5f..d14f98e 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -31,6 +31,7 @@
 #include <gdbus.h>
 #include <glib.h>
 #include <bluetooth/uuid.h>
+#include <stdlib.h>
 
 #include "dbus-common.h"
 #include "att.h"
@@ -45,6 +46,8 @@
 #include "server.h"
 #include "profile.h"
 #include "error.h"
+#include "textfile.h"
+#include "attio.h"
 
 #define PHONE_ALERT_STATUS_SVC_UUID		0x180E
 #define ALERT_NOTIF_SVC_UUID			0x1811
@@ -89,6 +92,11 @@ enum {
 	RINGER_NORMAL,
 };
 
+enum notify_type {
+	NOTIFY_RINGER_SETTING = 0,
+	NOTIFY_SIZE,
+};
+
 struct alert_data {
 	const char *category;
 	char *srv;
@@ -102,6 +110,21 @@ struct alert_adapter {
 	uint16_t supp_unread_alert_cat_handle;
 	uint16_t new_alert_handle;
 	uint16_t unread_alert_handle;
+	uint16_t hnd_ccc[NOTIFY_SIZE];
+	uint16_t hnd_value[NOTIFY_SIZE];
+};
+
+struct notify_data {
+	struct alert_adapter *al_adapter;
+	enum notify_type type;
+	uint8_t *value;
+	size_t len;
+};
+
+struct notify_callback {
+	struct notify_data *notify_data;
+	struct btd_device *device;
+	guint id;
 };
 
 static GSList *registered_alerts = NULL;
@@ -282,6 +305,125 @@ static void watcher_disconnect(DBusConnection *conn, void *user_data)
 	g_slist_foreach(alert_adapters, update_supported_categories, NULL);
 }
 
+static struct btd_device *get_notifiable_device(struct btd_adapter *adapter,
+						char *key, char *value,
+						uint16_t ccc)
+{
+	struct btd_device *device;
+	char addr[18];
+	uint16_t hnd, val;
+	uint8_t bdaddr_type;
+
+	sscanf(key, "%17s#%hhu#%04hX", addr, &bdaddr_type, &hnd);
+
+	if (hnd != ccc)
+		return NULL;
+
+	val = strtol(value, NULL, 16);
+	if (!(val & 0x0001))
+		return NULL;
+
+	device = adapter_find_device(adapter, addr);
+	if (device == NULL)
+		return NULL;
+
+	return btd_device_ref(device);
+}
+
+static void attio_connected_cb(GAttrib *attrib, gpointer user_data)
+{
+	struct notify_callback *cb = user_data;
+	struct notify_data *nd = cb->notify_data;
+	enum notify_type type = nd->type;
+	struct alert_adapter *al_adapter = nd->al_adapter;
+	uint8_t pdu[ATT_MAX_MTU];
+	size_t len = 0;
+
+	switch (type) {
+	case NOTIFY_RINGER_SETTING:
+		len = enc_notification(al_adapter->hnd_value[type],
+				&ringer_setting, sizeof(ringer_setting),
+				pdu, sizeof(pdu));
+		break;
+	default:
+		DBG("Unknown type, could not send notification");
+		goto end;
+	}
+
+	DBG("Send notification for handle: 0x%04x, ccc: 0x%04x",
+					al_adapter->hnd_value[type],
+					al_adapter->hnd_ccc[type]);
+
+	g_attrib_send(attrib, 0, ATT_OP_HANDLE_NOTIFY, pdu, len,
+							NULL, NULL, NULL);
+
+end:
+	btd_device_remove_attio_callback(cb->device, cb->id);
+	btd_device_unref(cb->device);
+	g_free(cb->notify_data->value);
+	g_free(cb->notify_data);
+	g_free(cb);
+}
+
+static void filter_devices_notify(char *key, char *value, void *user_data)
+{
+	struct notify_data *notify_data = user_data;
+	struct alert_adapter *al_adapter = notify_data->al_adapter;
+	enum notify_type type = notify_data->type;
+	struct btd_device *device;
+	struct notify_callback *cb;
+
+	device = get_notifiable_device(al_adapter->adapter, key, value,
+						al_adapter->hnd_ccc[type]);
+	if (device == NULL)
+		return;
+
+	cb = g_new0(struct notify_callback, 1);
+	cb->notify_data = notify_data;
+	cb->device = device;
+	cb->id = btd_device_add_attio_callback(device,
+						attio_connected_cb, NULL, cb);
+}
+
+static void create_filename(char *filename, struct btd_adapter *adapter)
+{
+	char srcaddr[18];
+	bdaddr_t src;
+
+	adapter_get_address(adapter, &src);
+	ba2str(&src, srcaddr);
+
+	create_name(filename, PATH_MAX, STORAGEDIR, srcaddr, "ccc");
+}
+
+static void notify_devices(struct alert_adapter *al_adapter,
+			enum notify_type type, uint8_t *value, size_t len)
+{
+	struct notify_data *notify_data;
+	char filename[PATH_MAX + 1];
+
+	notify_data = g_new0(struct notify_data, 1);
+	notify_data->al_adapter = al_adapter;
+	notify_data->type = type;
+	notify_data->value = g_memdup(value, len);
+	notify_data->len = len;
+
+	create_filename(filename, al_adapter->adapter);
+	textfile_foreach(filename, filter_devices_notify, notify_data);
+}
+
+static void pasp_notification(enum notify_type type)
+{
+	GSList *it;
+	struct alert_adapter *al_adapter;
+
+	for (it = alert_adapters; it; it = g_slist_next(it)) {
+		al_adapter = it->data;
+
+		notify_devices(al_adapter, type, NULL, 0);
+	}
+}
+
 static DBusMessage *register_alert(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
@@ -344,10 +486,15 @@ static void update_phone_alerts(const char *category, const char *description)
 	unsigned int i;
 
 	if (g_str_equal(category, "ringer")) {
-		if (g_str_equal(description, "enabled"))
+		if (g_str_equal(description, "enabled")) {
 			ringer_setting = RINGER_NORMAL;
-		else if (g_str_equal(description, "disabled"))
+			pasp_notification(NOTIFY_RINGER_SETTING);
+			return;
+		} else if (g_str_equal(description, "disabled")) {
 			ringer_setting = RINGER_SILENT;
+			pasp_notification(NOTIFY_RINGER_SETTING);
+			return;
+		}
 	}
 
 	for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++) {
@@ -619,6 +766,10 @@ static void register_phone_alert_service(struct alert_adapter *al_adapter)
 							ATT_CHAR_PROPER_NOTIFY,
 			GATT_OPT_CHR_VALUE_CB, ATTRIB_READ,
 			ringer_setting_read, al_adapter->adapter,
+			GATT_OPT_CCC_GET_HANDLE,
+			&al_adapter->hnd_ccc[NOTIFY_RINGER_SETTING],
+			GATT_OPT_CHR_VALUE_GET_HANDLE,
+			&al_adapter->hnd_value[NOTIFY_RINGER_SETTING],
 			GATT_OPT_INVALID);
 }
 
@@ -751,6 +902,7 @@ static void alert_server_remove(struct btd_adapter *adapter)
 
 	alert_adapters = g_slist_remove(alert_adapters, al_adapter);
 	btd_adapter_unref(al_adapter->adapter);
+
 	g_free(al_adapter);
 }
 
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH BlueZ 21/25] alert: Update Alert Status and Ringer Setting characteristic values
From: Anderson Lizardo @ 2012-09-24 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Anderson Lizardo
In-Reply-To: <1348509661-15967-1-git-send-email-anderson.lizardo@openbossa.org>

Now these characteristic values are updated when the agent changes any
PASP alert state or setting.
---
 profiles/alert/server.c |   24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 952d982..58d7c5f 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -339,6 +339,27 @@ static void update_new_alert(gpointer data, gpointer user_data)
 								value[0], NULL);
 }
 
+static void update_phone_alerts(const char *category, const char *description)
+{
+	unsigned int i;
+
+	if (g_str_equal(category, "ringer")) {
+		if (g_str_equal(description, "enabled"))
+			ringer_setting = RINGER_NORMAL;
+		else if (g_str_equal(description, "disabled"))
+			ringer_setting = RINGER_SILENT;
+	}
+
+	for (i = 0; i < G_N_ELEMENTS(pasp_categories); i++) {
+		if (g_str_equal(pasp_categories[i], category)) {
+			if (g_str_equal(description, "active"))
+				alert_status |= (1 << i);
+			else if (g_str_equal(description, "not active"))
+				alert_status &= ~(1 << i);
+		}
+	}
+}
+
 static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
 								void *data)
 {
@@ -399,6 +420,9 @@ static DBusMessage *new_alert(DBusConnection *conn, DBusMessage *msg,
 		}
 	}
 
+	if (pasp_category(category))
+		update_phone_alerts(category, description);
+
 	DBG("NewAlert(\"%s\", %d, \"%s\")", category, count, description);
 
 	return dbus_message_new_method_return(msg);
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH BlueZ 20/25] alert: Add test-alert script
From: Anderson Lizardo @ 2012-09-24 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348509661-15967-1-git-send-email-anderson.lizardo@openbossa.org>

From: Eder Ruiz Maria <eder.ruiz@openbossa.org>

This script is useful for testing the Alert API and testing the
implementation with PTS.
---
 test/test-alert |  173 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 173 insertions(+)
 create mode 100755 test/test-alert

diff --git a/test/test-alert b/test/test-alert
new file mode 100755
index 0000000..c92a719
--- /dev/null
+++ b/test/test-alert
@@ -0,0 +1,173 @@
+#!/usr/bin/python
+from __future__ import absolute_import, print_function, unicode_literals
+import dbus
+import dbus.service
+import dbus.mainloop.glib
+import gobject
+import optparse
+import sys
+import os
+
+BUS_NAME = 'org.bluez'
+ALERT_INTERFACE = 'org.bluez.Alert'
+ALERT_AGENT_INTERFACE = 'org.bluez.AlertAgent'
+BLUEZ_OBJECT_PATH = '/org/bluez'
+TEST_OBJECT_PATH = '/org/bluez/test'
+
+class AlertAgent(dbus.service.Object):
+	def __init__(self, bus, object_path, alert):
+		dbus.service.Object.__init__(self, bus, object_path)
+		self.alert = alert
+
+	@dbus.service.method(ALERT_AGENT_INTERFACE, in_signature='',
+							out_signature='')
+	def MuteOnce(self):
+		print('method MuteOnce() was called')
+		self.alert.NewAlert('ringer', 1, 'not active')
+
+	@dbus.service.method(ALERT_AGENT_INTERFACE, in_signature='s',
+							out_signature='')
+	def SetRinger(self, mode):
+		print('method SetRinger(%s) was called' % mode)
+		self.alert.NewAlert('ringer', 1, mode)
+
+def print_command_line(options):
+	if not options.verbose:
+		return False
+
+	print('-w: ' + str(options.wait))
+
+	if options.times:
+		print('-t: ' + str(options.times))
+
+	if options.register:
+		print('-r: ' + options.register)
+	else:
+		print('-r: ' + str(None))
+
+	if options.new_alert:
+		print('-n:')
+		for i in options.new_alert:
+			print('    ' + i[0] + ', ' + i[1] + ', ' + i[2])
+	else:
+		print('-n: ' + str(None))
+
+	if options.unread_alert:
+		print('-u:')
+		for i in options.unread_alert:
+			print('    ' + i[0] + ', ' + i[1])
+	else:
+		print('-u: ' + str(None))
+
+	print()
+
+	return True
+
+def read_count(param):
+	try:
+		return int(param)
+	except ValueError:
+		print('<count> must be integer, not \"%s\"' % param)
+		sys.exit(1)
+
+def new_alert(alert, params):
+	if not params:
+		return False
+
+	for param in params:
+		category = param[0]
+		count = read_count(param[1])
+		description = param[2]
+
+		alert.NewAlert(category, count, description)
+
+def unread_alert(alert, params):
+	if not params:
+		return False
+
+	for param in params:
+		category = param[0]
+		count = read_count(param[1])
+
+		alert.UnreadAlert(category, count)
+
+option_list = [
+	optparse.make_option('-v', None,
+			action = 'store_true',
+			default = False,
+			dest = 'verbose',
+			help = 'verbose'),
+
+	optparse.make_option('-w', None,
+			action = 'store_true',
+			default = False,
+			dest = 'wait',
+			help = 'wait for dbus events'),
+
+	optparse.make_option('-t', None,
+			action = 'store',
+			default = 1,
+			type = "int",
+			dest = 'times',
+			help = 'repeat UnreadAlert/NewAlert <times> times',
+			metavar = '<times>'),
+
+	optparse.make_option('-r', None,
+			action = 'store',
+			dest = 'register',
+			type = 'string',
+			metavar = '<category>',
+			help = 'register alert'),
+
+	optparse.make_option('-n', None,
+			action = 'append',
+			dest = 'new_alert',
+			type = 'string',
+			nargs = 3,
+			metavar = '<category> <count> <description>',
+			help = 'send new alert'),
+
+	optparse.make_option('-u', None,
+			action = 'append',
+			dest = 'unread_alert',
+			type = 'string',
+			nargs = 2,
+			metavar = '<category> <count>',
+			help = 'send unread alert'),
+]
+
+parser = optparse.OptionParser(option_list=option_list)
+parser.disable_interspersed_args()
+(options, args) = parser.parse_args()
+
+dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+bus = dbus.SystemBus()
+mainloop = gobject.MainLoop()
+alert = dbus.Interface(bus.get_object(BUS_NAME, BLUEZ_OBJECT_PATH),
+								ALERT_INTERFACE)
+alert_agent = AlertAgent(bus, TEST_OBJECT_PATH, alert)
+
+print_command_line(options)
+
+if not (options.register or options.new_alert or options.unread_alert or
+								options.wait):
+	parser.print_usage()
+	sys.exit(1)
+
+if options.register:
+	alert.RegisterAlert(options.register, TEST_OBJECT_PATH)
+
+times = 0
+while times < options.times:
+	times += 1
+
+	new_alert(alert, options.new_alert)
+	unread_alert(alert, options.unread_alert)
+
+if not options.wait:
+	sys.exit(0)
+
+try:
+	mainloop.run()
+except:
+	pass
-- 
1.7.9.5


^ permalink raw reply related

* [PATCH BlueZ 19/25] alert: Add support for calling SetRinger()
From: Anderson Lizardo @ 2012-09-24 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Eder Ruiz Maria
In-Reply-To: <1348509661-15967-1-git-send-email-anderson.lizardo@openbossa.org>

From: Eder Ruiz Maria <eder.ruiz@openbossa.org>

When BlueZ wants to call SetRinger() method from org.bluez.AlertAgent
interface for a registered agent, the function agent_ringer_set_ringer()
must be called.
---
 profiles/alert/server.c |   27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)

diff --git a/profiles/alert/server.c b/profiles/alert/server.c
index 75eb414..952d982 100644
--- a/profiles/alert/server.c
+++ b/profiles/alert/server.c
@@ -426,6 +426,31 @@ static int agent_ringer_mute_once(void)
 	return 0;
 }
 
+static int agent_ringer_set_ringer(const char *mode)
+{
+	struct alert_data *alert;
+	DBusMessage *msg;
+
+	alert = get_alert_data_by_category("ringer");
+	if (!alert) {
+		DBG("Category ringer is not registered");
+		return -EINVAL;
+	}
+
+	msg = dbus_message_new_method_call(alert->srv, alert->path,
+					ALERT_AGENT_INTERFACE, "SetRinger");
+	if (!msg)
+		return -ENOMEM;
+
+	dbus_message_append_args(msg, DBUS_TYPE_STRING, &mode,
+							DBUS_TYPE_INVALID);
+
+	dbus_message_set_no_reply(msg, TRUE);
+	g_dbus_send_message(btd_get_dbus_connection(), msg);
+
+	return 0;
+}
+
 static void update_unread_alert(gpointer data, gpointer user_data)
 {
 	struct alert_adapter *al_adapter = data;
@@ -498,6 +523,7 @@ static uint8_t ringer_cp_write(struct attribute *a,
 	switch (a->data[0]) {
 	case RINGER_SILENT_MODE:
 		DBG("Silent Mode");
+		agent_ringer_set_ringer("disabled");
 		break;
 	case RINGER_MUTE_ONCE:
 		DBG("Mute Once");
@@ -505,6 +531,7 @@ static uint8_t ringer_cp_write(struct attribute *a,
 		break;
 	case RINGER_CANCEL_SILENT_MODE:
 		DBG("Cancel Silent Mode");
+		agent_ringer_set_ringer("enabled");
 		break;
 	default:
 		DBG("Invalid command (0x%02x)", a->data[0]);
-- 
1.7.9.5


^ permalink raw reply related


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