From: Frederic Danis <frederic.danis@access-company.com>
To: BlueZ development <bluez-devel@lists.sourceforge.net>
Subject: Re: [Bluez-devel] HID certification using PTS
Date: Tue, 01 Apr 2008 17:56:32 +0200 [thread overview]
Message-ID: <47F25B30.8050108@access-company.com> (raw)
In-Reply-To: <47EA7502.0@access-company.com>
[-- Attachment #1: Type: text/plain, Size: 972 bytes --]
Hello,
> - when kernel (2.6.22) receives a VIRTUAL_CABLE_UNPLUG from PTS (tests
> TC_HOS_HCR_BV_02_I and TC_HOS_HCR_BV_04_I) it does not close the L2CAP
> channels as PTS waits for.
> I take a look in 2.6.22 sources, and it seems to me this disconnection
> should happen, am I right ?
> Is it fixed in later kernel ?
Regarding this problem I wrote a patch in kernel that allows to poll the HIDP control socket and set it to IO_HUP when receiving the virtual cable unplug command.
I update the input service to watch the HIDP control socket and close l2cap sockets if IO_HUP is set on HIDP control socket.
Is it OK ?
Regards
Fred
--
-----------------------------------------------
It is not by improving the oil lamp that one invents the electric bulb!
-----------------------------------------------
Danis Frederic Access Company
Software engineer
Mail : mailto:frederic.danis@access-company.com
-----------------------------------------------
[-- Attachment #2: hidp_socket.patch --]
[-- Type: text/x-patch, Size: 3435 bytes --]
diff -Naur linux-2.6.24.4/net/bluetooth/hidp.orig/core.c linux-2.6.24.4/net/bluetooth/hidp/core.c
--- linux-2.6.24.4/net/bluetooth/hidp.orig/core.c 2008-03-24 19:49:18.000000000 +0100
+++ linux-2.6.24.4/net/bluetooth/hidp/core.c 2008-04-01 11:14:05.000000000 +0200
@@ -378,8 +378,12 @@
skb_queue_purge(&session->ctrl_transmit);
skb_queue_purge(&session->intr_transmit);
+ if (session->hidp_sock)
+ session->hidp_sock->sk->sk_shutdown = SHUTDOWN_MASK;
+
/* Kill session thread */
atomic_inc(&session->terminate);
+ hidp_schedule(session);
break;
case HIDP_CTRL_HARD_RESET:
@@ -743,7 +747,7 @@
hid->claimed |= HID_CLAIMED_INPUT;
}
-int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock)
+int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock, struct socket *hidp_sock)
{
struct hidp_session *session, *s;
int err;
@@ -809,6 +813,7 @@
session->ctrl_sock = ctrl_sock;
session->intr_sock = intr_sock;
+ session->hidp_sock = hidp_sock;
session->state = BT_CONNECTED;
init_timer(&session->timer);
@@ -952,6 +957,24 @@
return err;
}
+void hidp_remove_hidp_sock_ref(struct socket *hidp_sock)
+{
+ struct list_head *p;
+
+ down_read(&hidp_session_sem);
+
+ list_for_each(p, &hidp_session_list) {
+ struct hidp_session *session;
+
+ session = list_entry(p, struct hidp_session, list);
+
+ if (session->hidp_sock == hidp_sock)
+ session->hidp_sock = NULL;
+ }
+
+ up_read(&hidp_session_sem);
+}
+
static int __init hidp_init(void)
{
l2cap_load();
diff -Naur linux-2.6.24.4/net/bluetooth/hidp.orig/hidp.h linux-2.6.24.4/net/bluetooth/hidp/hidp.h
--- linux-2.6.24.4/net/bluetooth/hidp.orig/hidp.h 2008-03-24 19:49:18.000000000 +0100
+++ linux-2.6.24.4/net/bluetooth/hidp/hidp.h 2008-04-01 11:14:33.000000000 +0200
@@ -117,10 +117,11 @@
struct hidp_conninfo __user *ci;
};
-int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock);
+int hidp_add_connection(struct hidp_connadd_req *req, struct socket *ctrl_sock, struct socket *intr_sock, struct socket *hidp_sock);
int hidp_del_connection(struct hidp_conndel_req *req);
int hidp_get_connlist(struct hidp_connlist_req *req);
int hidp_get_conninfo(struct hidp_conninfo *ci);
+void hidp_remove_hidp_sock_ref(struct socket *hidp_sock);
/* HIDP session defines */
struct hidp_session {
@@ -128,6 +129,7 @@
struct socket *ctrl_sock;
struct socket *intr_sock;
+ struct socket *hidp_sock;
bdaddr_t bdaddr;
diff -Naur linux-2.6.24.4/net/bluetooth/hidp.orig/sock.c linux-2.6.24.4/net/bluetooth/hidp/sock.c
--- linux-2.6.24.4/net/bluetooth/hidp.orig/sock.c 2008-03-24 19:49:18.000000000 +0100
+++ linux-2.6.24.4/net/bluetooth/hidp/sock.c 2008-04-01 11:15:33.000000000 +0200
@@ -56,6 +56,8 @@
sock_orphan(sk);
sock_put(sk);
+ hidp_remove_hidp_sock_ref(sock);
+
return 0;
}
@@ -96,7 +98,7 @@
return -EBADFD;
}
- err = hidp_add_connection(&ca, csock, isock);
+ err = hidp_add_connection(&ca, csock, isock, sock);
if (!err) {
if (copy_to_user(argp, &ca, sizeof(ca)))
err = -EFAULT;
@@ -229,7 +231,7 @@
.getname = sock_no_getname,
.sendmsg = sock_no_sendmsg,
.recvmsg = sock_no_recvmsg,
- .poll = sock_no_poll,
+ .poll = bt_sock_poll,
.listen = sock_no_listen,
.shutdown = sock_no_shutdown,
.setsockopt = sock_no_setsockopt,
[-- Attachment #3: virtual_cable_unplug.patch --]
[-- Type: text/x-patch, Size: 4034 bytes --]
Index: device.c
===================================================================
RCS file: /cvsroot/bluez/utils/input/device.c,v
retrieving revision 1.71
diff -a -u -r1.71 device.c
--- device.c 14 Mar 2008 18:44:00 -0000 1.71
+++ device.c 1 Apr 2008 15:42:26 -0000
@@ -78,8 +78,10 @@
char *path;
int ctrl_sk;
int intr_sk;
+ int hidp_sk;
guint ctrl_watch;
guint intr_watch;
+ guint hidp_watch;
};
GSList *devices = NULL;
@@ -524,8 +526,10 @@
DBUS_TYPE_INVALID);
g_source_remove(idev->ctrl_watch);
+ g_source_remove(idev->hidp_watch);
idev->ctrl_watch = 0;
idev->intr_watch = 0;
+ idev->hidp_watch = 0;
/* Close control channel */
if (idev->ctrl_sk > 0) {
@@ -533,6 +537,12 @@
idev->ctrl_sk = -1;
}
+ /* Close hidp channel */
+ if (idev->hidp_sk > 0) {
+ close(idev->hidp_sk);
+ idev->hidp_sk = -1;
+ }
+
return FALSE;
}
@@ -551,8 +561,10 @@
DBUS_TYPE_INVALID);
g_source_remove(idev->intr_watch);
+ g_source_remove(idev->hidp_watch);
idev->intr_watch = 0;
idev->ctrl_watch = 0;
+ idev->hidp_watch = 0;
/* Close interrupt channel */
if (idev->intr_sk > 0) {
@@ -560,6 +572,47 @@
idev->intr_sk = -1;
}
+ /* Close hidp channel */
+ if (idev->hidp_sk > 0) {
+ close(idev->hidp_sk);
+ idev->hidp_sk = -1;
+ }
+
+ return FALSE;
+}
+
+static gboolean hidp_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
+{
+ struct device *idev = data;
+
+ if (cond & (G_IO_HUP | G_IO_ERR)) {
+ g_io_channel_close(chan);
+ }
+
+ dbus_connection_emit_signal(idev->conn,
+ idev->path,
+ INPUT_DEVICE_INTERFACE,
+ "Disconnected",
+ DBUS_TYPE_INVALID);
+
+ g_source_remove(idev->intr_watch);
+ g_source_remove(idev->ctrl_watch);
+ idev->intr_watch = 0;
+ idev->ctrl_watch = 0;
+ idev->hidp_watch = 0;
+
+ /* Close interrupt channel */
+ if (idev->intr_sk > 0) {
+ close(idev->intr_sk);
+ idev->intr_sk = -1;
+ }
+
+ /* Close control channel */
+ if (idev->ctrl_sk > 0) {
+ close(idev->ctrl_sk);
+ idev->ctrl_sk = -1;
+ }
+
return FALSE;
}
@@ -620,12 +673,10 @@
err = ioctl(ctl, HIDPCONNADD, &req);
cleanup:
- close(ctl);
-
if (req.rd_data)
free(req.rd_data);
- return err;
+ return ctl;
}
static gboolean interrupt_connect_cb(GIOChannel *chan,
@@ -663,13 +714,14 @@
}
idev->intr_sk = isk;
- err = hidp_connadd(&idev->src, &idev->dst,
+ idev->hidp_sk = hidp_connadd(&idev->src, &idev->dst,
idev->ctrl_sk, idev->intr_sk, idev->name);
- if (err < 0)
+ if (idev->hidp_sk < 0)
goto failed;
idev->intr_watch = create_watch(idev->intr_sk, intr_watch_cb, idev);
idev->ctrl_watch = create_watch(idev->ctrl_sk, ctrl_watch_cb, idev);
+ idev->hidp_watch = create_watch(idev->hidp_sk, hidp_watch_cb, idev);
dbus_connection_emit_signal(idev->conn,
idev->path,
INPUT_DEVICE_INTERFACE,
@@ -802,10 +854,15 @@
idev->intr_sk = -1;
}
- ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP);
- if (ctl < 0) {
- error("Can't open HIDP control socket");
- return -errno;
+ if (idev->hidp_sk >= 0) {
+ ctl = idev->hidp_sk;
+ idev->hidp_sk = -1;
+ } else {
+ ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP);
+ if (ctl < 0) {
+ error("Can't open HIDP control socket");
+ return -errno;
+ }
}
memset(&ci, 0, sizeof(ci));
@@ -1181,6 +1238,9 @@
* to access the D-Bus data assigned to this path
* because the object path data was destroyed.
*/
+ if (idev->hidp_watch)
+ g_source_remove(idev->hidp_watch);
+
if (idev->ctrl_watch)
g_source_remove(idev->ctrl_watch);
@@ -1364,8 +1424,15 @@
fake->disconnect = fake_hid_disconnect;
fake->priv = fake_hid;
err = fake_hid_connadd(fake, idev->intr_sk, fake_hid);
- } else
- err = hidp_connadd(src, dst, idev->ctrl_sk, idev->intr_sk, idev->name);
+ } else {
+ idev->hidp_sk = hidp_connadd(src, dst, idev->ctrl_sk, idev->intr_sk, idev->name);
+ if (idev->hidp_sk < 0) {
+ err = idev->hidp_sk;
+ } else {
+ err = 0;
+ idev->hidp_watch = create_watch(idev->hidp_sk, hidp_watch_cb, idev);
+ }
+ }
if (err < 0)
goto error;
[-- Attachment #4: Type: text/plain, Size: 278 bytes --]
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
[-- Attachment #5: Type: text/plain, Size: 164 bytes --]
_______________________________________________
Bluez-devel mailing list
Bluez-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-devel
prev parent reply other threads:[~2008-04-01 15:56 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-03-26 16:08 [Bluez-devel] HID certification using PTS Frederic Danis
2008-03-26 16:16 ` Marcel Holtmann
2008-03-27 10:45 ` Frederic Danis
2008-03-27 15:09 ` Marcel Holtmann
2008-03-27 16:08 ` Frederic Danis
2008-03-31 8:53 ` Frederic Danis
2008-04-01 15:56 ` Frederic Danis [this message]
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=47F25B30.8050108@access-company.com \
--to=frederic.danis@access-company.com \
--cc=bluez-devel@lists.sourceforge.net \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.