From: Jean Tourrilhes <jt@bougret.hpl.hp.com>
To: BlueZ mailing list <bluez-devel@lists.sourceforge.net>,
Marcel Holtmann <marcel@holtmann.org>
Subject: Re: Re: out of range
Date: Wed, 12 Jan 2005 10:38:06 -0800 [thread overview]
Message-ID: <20050112183806.GE31615@bougret.hpl.hp.com> (raw)
Marcel Holtmann wrote :
>
> Hi Mike,
>
> > Then how can i determind whether rfcomm is terminated by user or
> > due to out of range? Or i need to monitor hci msg?
>
> I think there is no way to differ between it yet. Feel free to propose
> an idea how that should be done within the normal socket operation.
Marcel : I did propose to you a scheme to detect out of range
conditions ahead of the Supervision Timeout that would clearly also
work for this.
Mike : please try that attached patch, you will obviously need
to study it to understand how to make use of it. The HCI disconnection
complete event contain the "reason", but I've never tried that.
Good luck...
Jean
--------------------------------------------------
diff -u -p linux/net/bluetooth/Kconfig.m1 linux/net/bluetooth/Kconfig
--- linux/net/bluetooth/Kconfig.m1 Mon Nov 1 14:06:15 2004
+++ linux/net/bluetooth/Kconfig Mon Nov 1 14:07:07 2004
@@ -60,4 +60,14 @@ source "net/bluetooth/cmtp/Kconfig"
source "net/bluetooth/hidp/Kconfig"
source "drivers/bluetooth/Kconfig"
+
+config BT_WARNDELAY
+ bool "ACL delay warning"
+ depends on BT
+ help
+ Trigger a HCI event is ACL transmit did not complete in a certain
+ time. This is a "link trigger" used to optimise most Ad-Hoc
+ routing protocols such as AODV, and can be used when you need to
+ know very quickly if a L2CAP connection is going bad...
+ Just say N if you don't understand the above.
diff -u -p linux/include/net/bluetooth/hci.m1.h linux/include/net/bluetooth/hci.h
--- linux/include/net/bluetooth/hci.m1.h Mon Nov 1 14:05:37 2004
+++ linux/include/net/bluetooth/hci.h Mon Nov 1 14:08:13 2004
@@ -97,6 +97,7 @@ enum {
#define HCISETSECMGR _IOW('H', 230, int)
#define HCIINQUIRY _IOR('H', 240, int)
+#define HCISETWARNDELAY _IOW('H', 245, int)
/* HCI timeouts */
#define HCI_CONN_TIMEOUT (HZ * 40)
@@ -574,6 +575,12 @@ struct hci_ev_si_security {
__u16 proto;
__u16 subproto;
__u8 incoming;
+} __attribute__ ((packed));
+
+#define HCI_EV_SI_WARNDELAY 0x03
+struct hci_ev_si_warndelay {
+ __u16 handle;
+ __u32 delay; /* ms */
} __attribute__ ((packed));
/* ---- HCI Packet structures ---- */
diff -u -p linux/include/net/bluetooth/hci_core.m1.h linux/include/net/bluetooth/hci_core.h
--- linux/include/net/bluetooth/hci_core.m1.h Mon Nov 1 14:05:46 2004
+++ linux/include/net/bluetooth/hci_core.h Mon Nov 1 14:07:07 2004
@@ -73,6 +73,9 @@ struct hci_dev {
__u16 pkt_type;
__u16 link_policy;
__u16 link_mode;
+#ifdef CONFIG_BT_WARNDELAY
+ unsigned long warn_delay;
+#endif /* CONFIG_BT_WARNDELAY */
unsigned long quirks;
@@ -146,6 +149,10 @@ struct hci_conn {
unsigned long pend;
unsigned int sent;
+#ifdef CONFIG_BT_WARNDELAY
+ unsigned long last_ack;
+ struct timer_list warndelay_timer;
+#endif /* CONFIG_BT_WARNDELAY */
struct sk_buff_head data_q;
diff -u -p linux/net/bluetooth/hci_conn.m1.c linux/net/bluetooth/hci_conn.c
--- linux/net/bluetooth/hci_conn.m1.c Mon Nov 1 14:06:25 2004
+++ linux/net/bluetooth/hci_conn.c Mon Nov 1 14:07:07 2004
@@ -140,6 +140,35 @@ static void hci_conn_init_timer(struct h
conn->timer.data = (unsigned long)conn;
}
+#ifdef CONFIG_BT_WARNDELAY
+static void hci_warndelay_timeout(unsigned long arg)
+{
+ struct hci_conn *conn = (void *)arg;
+ struct hci_dev *hdev = conn->hdev;
+ struct hci_ev_si_warndelay ev;
+
+ /* We didn't receive the Tx ack in the expected time, generate
+ * an event to user space. Jean II */
+
+ BT_DBG("conn %p state %d", conn, conn->state);
+
+ hci_dev_lock(hdev);
+
+ /* Send event to HCI sockets */
+ ev.handle = conn->handle;
+ ev.delay = (jiffies - conn->last_ack) * 1000 / HZ;
+ hci_si_event(NULL, HCI_EV_SI_WARNDELAY,
+ sizeof(ev), &ev);
+
+ /* Re-arm timer */
+ mod_timer(&(conn->warndelay_timer),
+ jiffies + hdev->warn_delay);
+
+ hci_dev_unlock(hdev);
+ return;
+}
+#endif /* CONFIG_BT_WARNDELAY */
+
struct hci_conn *hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t *dst)
{
struct hci_conn *conn;
@@ -157,6 +186,12 @@ struct hci_conn *hci_conn_add(struct hci
skb_queue_head_init(&conn->data_q);
hci_conn_init_timer(conn);
+#ifdef CONFIG_BT_WARNDELAY
+ /* This timer generates event on ACL stalls. Jean II */
+ init_timer(&conn->warndelay_timer);
+ conn->warndelay_timer.function = hci_warndelay_timeout;
+ conn->warndelay_timer.data = (unsigned long) conn;
+#endif /* CONFIG_BT_WARNDELAY */
atomic_set(&conn->refcnt, 0);
@@ -180,6 +215,10 @@ int hci_conn_del(struct hci_conn *conn)
BT_DBG("%s conn %p handle %d", hdev->name, conn, conn->handle);
hci_conn_del_timer(conn);
+#ifdef CONFIG_BT_WARNDELAY
+ if(timer_pending(&(conn->warndelay_timer)))
+ del_timer(&(conn->warndelay_timer));
+#endif /* CONFIG_BT_WARNDELAY */
if (conn->type == SCO_LINK) {
struct hci_conn *acl = conn->link;
diff -u -p linux/net/bluetooth/hci_core.m1.c linux/net/bluetooth/hci_core.c
--- linux/net/bluetooth/hci_core.m1.c Mon Nov 1 14:06:33 2004
+++ linux/net/bluetooth/hci_core.c Mon Nov 1 14:07:07 2004
@@ -677,6 +677,17 @@ int hci_dev_cmd(unsigned int cmd, void _
hdev->sco_pkts = *((__u16 *)&dr.dev_opt + 0);
break;
+#ifdef CONFIG_BT_WARNDELAY
+ case HCISETWARNDELAY:
+ /* This setting is "per interface". You may want to do
+ * it "per connection", but that's much more messy.
+ * To disable, set 0
+ * The value is in ms, so convert it to jiffies.
+ * Jean II */
+ hdev->warn_delay = (unsigned long) dr.dev_opt * HZ / 1000;
+ break;
+#endif /* CONFIG_BT_WARNDELAY */
+
default:
err = -EINVAL;
break;
@@ -816,6 +827,9 @@ int hci_register_dev(struct hci_dev *hde
hdev->flags = 0;
hdev->pkt_type = (HCI_DM1 | HCI_DH1 | HCI_HV1);
hdev->link_mode = (HCI_LM_ACCEPT);
+#ifdef CONFIG_BT_WARNDELAY
+ hdev->warn_delay = 0; /* Disabled */
+#endif /* CONFIG_BT_WARNDELAY */
tasklet_init(&hdev->cmd_task, hci_cmd_task,(unsigned long) hdev);
tasklet_init(&hdev->rx_task, hci_rx_task, (unsigned long) hdev);
@@ -1166,6 +1180,15 @@ static inline void hci_sched_acl(struct
BT_DBG("skb %p len %d", skb, skb->len);
hci_send_frame(skb);
hdev->acl_last_tx = jiffies;
+
+#ifdef CONFIG_BT_WARNDELAY
+ /* Start the warndelay timer if not pending */
+ if ((conn->sent == 0) && (hdev->warn_delay != 0)) {
+ conn->last_ack = jiffies;
+ conn->warndelay_timer.expires = jiffies + hdev->warn_delay;
+ add_timer(&(conn->warndelay_timer));
+ }
+#endif /* CONFIG_BT_WARNDELAY */
hdev->acl_cnt--;
conn->sent++;
diff -u -p linux/net/bluetooth/hci_event.m1.c linux/net/bluetooth/hci_event.c
--- linux/net/bluetooth/hci_event.m1.c Mon Nov 1 14:06:42 2004
+++ linux/net/bluetooth/hci_event.c Mon Nov 1 14:07:07 2004
@@ -684,6 +684,21 @@ static inline void hci_num_comp_pkts_evt
if (conn) {
conn->sent -= count;
+#ifdef CONFIG_BT_WARNDELAY
+ if ((count) && (conn->type == ACL_LINK) &&
+ (hdev->warn_delay != 0)) {
+ if (conn->sent == 0) {
+ /* No pending packets, cancel */
+ del_timer(&(conn->warndelay_timer));
+ } else {
+ /* Pending packets, re-arm */
+ conn->last_ack = jiffies;
+ mod_timer(&(conn->warndelay_timer),
+ jiffies + hdev->warn_delay);
+ }
+ }
+#endif /* CONFIG_BT_WARNDELAY */
+
if (conn->type == SCO_LINK) {
if ((hdev->sco_cnt += count) > hdev->sco_pkts)
hdev->sco_cnt = hdev->sco_pkts;
diff -u -p linux/net/bluetooth/hci_sock.m1.c linux/net/bluetooth/hci_sock.c
--- linux/net/bluetooth/hci_sock.m1.c Mon Nov 1 14:06:59 2004
+++ linux/net/bluetooth/hci_sock.c Mon Nov 1 14:07:07 2004
@@ -252,6 +252,7 @@ static int hci_sock_ioctl(struct socket
case HCISETLINKMODE:
case HCISETACLMTU:
case HCISETSCOMTU:
+ case HCISETWARNDELAY:
if (!capable(CAP_NET_ADMIN))
return -EACCES;
return hci_dev_cmd(cmd, argp);
next reply other threads:[~2005-01-12 18:38 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2005-01-12 18:38 Jean Tourrilhes [this message]
2005-01-12 20:32 ` [Bluez-devel] Re: out of range Marcel Holtmann
2005-01-12 21:25 ` Jean Tourrilhes
2005-01-12 23:15 ` [Bluez-devel] " Marcel Holtmann
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20050112183806.GE31615@bougret.hpl.hp.com \
--to=jt@bougret.hpl.hp.com \
--cc=bluez-devel@lists.sourceforge.net \
--cc=jt@hpl.hp.com \
--cc=marcel@holtmann.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox