Linux bluetooth development
 help / color / mirror / Atom feed
* [2.4.30] RFCOMM race
@ 2005-09-29 12:25 gl
  2005-09-29 16:38 ` [Bluez-users] " Marcel Holtmann
  0 siblings, 1 reply; 3+ messages in thread
From: gl @ 2005-09-29 12:25 UTC (permalink / raw)
  To: bluez-users; +Cc: marcel, Maksim Krasnyanskiy

[-- Attachment #1: Type: TEXT/PLAIN, Size: 1165 bytes --]

Hi Marcel, Max, the list

I have a "buggy" user-space program (attached, careful - it IS buggy:-)), 
communicating over rfcomm, that quite often hangs itself in the 
uninterruptible (D) state.

Ok, the program IS buggy, but, I think, it shouldn't hang in "D" and 
render the entire Bluetooth subsystem unusable?

How: it forks, the child tries to connect to a non-existing peer, at this 
time the parent issues ioctl(HCIDEVDOWN); ioctl(HCIDEVUP); the DOWN wakes 
the child up and it dows ioctl(HCIDEVDOWN) too. That's it. On the 
USB-analyser I see an incomplete HCI Reset, interrupted by the "Read local 
supported features" - from the UP. (screenshot attached)

The question is, of course, where (apart from the program) is the bug? I 
have to say, that the bluletooth module is connected to an "unsupported" 
USB controller, the driver for which I am debugging. I thought, naturally, 
that the bug is there. But now I am not sure. Is this really the case? If 
yes, what might it be doing wrong? Or is it rfcomm?

Thanks
Guennadi
---------------------------------
Guennadi Liakhovetski, Ph.D.
DSA Daten- und Systemtechnik GmbH
Pascalstr. 28
D-52076 Aachen
Germany

[-- Attachment #2: Type: TEXT/x-csrc, Size: 3850 bytes --]

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>			// fuer sleep, read, write
#include <termios.h>			// fuer cfmakeraw
#include <string.h>
#include <errno.h>
#include <ctype.h>			// fuer isprint, tolower
#include <sys/time.h>			// fuer timeval
#include <netinet/in.h>			/* fuer sa_family_t fuer hci.h */
#include <fcntl.h>
#include <sys/ioctl.h> 
#include <sys/poll.h>

#define _USE_BSD
#include <sys/types.h>
#include <sys/resource.h>
#include <sys/wait.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>

//#define DEBUG
#ifdef DEBUG
#define pause_if_debug(t) sleep(t)
#else
#define pause_if_debug(t) do {} while (0)
#endif

static int pipe_fd[2];

static void parent(int argc, char *argv[])
{
	int ctl;
	int hci_id;
	char c = 0;

	sleep(3);
	pause_if_debug(5);
	hci_id = hci_devid("hci0");

	if ((ctl = hci_open_dev(hci_id)) < 0)
		return;

	ioctl(ctl, HCIDEVDOWN, hci_id);
	pause_if_debug(1);
	ioctl(ctl, HCIDEVUP, hci_id);
	write(pipe_fd[1], &c, 1);

	wait3(NULL, 0, NULL);
	ioctl(ctl, HCIDEVUP, hci_id);

	hci_close_dev(ctl);
}

static void child(int argc, char *argv[])
{
	bdaddr_t bdaddr_remote, bdaddr_local; 
	struct sockaddr_rc laddr, raddr;
	struct rfcomm_dev_req req;
	struct termios ti;
	char devname[30];
	int sock, addr_len;
	int ctl, rfcomm = -1;
	int hci_id;
	int err;
	char str[] = "Hello, rfcomm.\n", remote[20];
	char c;

	sleep(1);
	hci_id = hci_devid("hci0");
	sprintf(str, "Hello, rfcomm%.1d\n", hci_id);
	puts(str);

	if ((ctl = hci_open_dev(hci_id)) < 0)
		return;

	pause_if_debug(1);
	err = ioctl(ctl, HCIDEVUP, hci_id);
	pause_if_debug(1);
	hci_close_dev(ctl);

	if (err < 0 && errno != EALREADY)
		return;

	if (hci_devba(hci_id, &bdaddr_local) < 0)
		return;

	pause_if_debug(1);
//	str2ba(ba_local, &bdaddr_local);
	laddr.rc_family = AF_BLUETOOTH;
	bacpy(&laddr.rc_bdaddr, &bdaddr_local);
	laddr.rc_channel = 0;

	str2ba(argv[1], &bdaddr_remote);
	raddr.rc_family = AF_BLUETOOTH;
	bacpy(&raddr.rc_bdaddr, &bdaddr_remote);	// Remote BT-address
	raddr.rc_channel = 1;			// Channel

	if ((sock = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM)) < 0)
		goto out2;

	pause_if_debug(1);
	if (bind(sock, (struct sockaddr *)&laddr, sizeof(laddr)) < 0)
		goto out2;

	pause_if_debug(1);
	ba2str(&raddr.rc_bdaddr, remote);
	printf("connect to %s\n", remote);

	if (connect(sock, (struct sockaddr *)&raddr, sizeof(raddr)) < 0) {
		pause_if_debug(2);
		if ((ctl = hci_open_dev(hci_id)) >= 0) {
			pause_if_debug(1);
			ioctl(ctl, HCIDEVDOWN, hci_id);
			pause_if_debug(1);
			hci_close_dev(ctl);
		}
		printf("%s\n", strerror(errno));
		goto out2;
	}

	addr_len = sizeof(laddr);

	if (getsockname(sock, (struct sockaddr *)&laddr, &addr_len) < 0)
		goto out2;

	memset(&req, 0, sizeof(req));
	req.dev_id = hci_id;
	req.flags = (1 << RFCOMM_REUSE_DLC) | (1 << RFCOMM_RELEASE_ONHUP);

	bacpy(&req.src, &laddr.rc_bdaddr);
	bacpy(&req.dst, &raddr.rc_bdaddr);
	req.channel = raddr.rc_channel;

	if ((hci_id = ioctl(sock, RFCOMMCREATEDEV, &req)) < 0)
		goto out2;

	sprintf(devname, "/dev/rfcomm%d", hci_id); 

//	sleep(2);

	if ((rfcomm = open(devname, O_RDWR | O_NOCTTY)) < 0)
		goto out2;

	// fuer rfcomm-raw-tty-device, ggf. entf.
	tcflush(rfcomm, TCIOFLUSH); 
	cfmakeraw(&ti);
	tcsetattr(rfcomm, TCSANOW, &ti); 

//	sleep(2);

	if (write(rfcomm, str, strlen(str)) < 0)
		printf("error %s\n", strerror(errno));

out2:
	read(pipe_fd[0], &c, 1);

	if (rfcomm > 0)
		close(rfcomm);

	close(sock);
}

int main(int argc, char *argv[])
{
	int pid;

	if (pipe(pipe_fd) < 0)
		exit(1);

	pid = fork();
	if (pid)
		parent(argc, argv);
	else
		child(argc, argv);

	exit(0);
}

[-- Attachment #3: Type: IMAGE/JPEG, Size: 101892 bytes --]

^ permalink raw reply	[flat|nested] 3+ messages in thread

* [Bluez-users] Re: [2.4.30] RFCOMM race
  2005-09-29 12:25 [2.4.30] RFCOMM race gl
@ 2005-09-29 16:38 ` Marcel Holtmann
  2005-09-30 12:18   ` gl
  0 siblings, 1 reply; 3+ messages in thread
From: Marcel Holtmann @ 2005-09-29 16:38 UTC (permalink / raw)
  To: gl; +Cc: bluez-users, Maksim Krasnyanskiy

Hi Guennadi,

> I have a "buggy" user-space program (attached, careful - it IS buggy:-)), 
> communicating over rfcomm, that quite often hangs itself in the 
> uninterruptible (D) state.
> 
> Ok, the program IS buggy, but, I think, it shouldn't hang in "D" and 
> render the entire Bluetooth subsystem unusable?
> 
> How: it forks, the child tries to connect to a non-existing peer, at this 
> time the parent issues ioctl(HCIDEVDOWN); ioctl(HCIDEVUP); the DOWN wakes 
> the child up and it dows ioctl(HCIDEVDOWN) too. That's it. On the 
> USB-analyser I see an incomplete HCI Reset, interrupted by the "Read local 
> supported features" - from the UP. (screenshot attached)
> 
> The question is, of course, where (apart from the program) is the bug? I 
> have to say, that the bluletooth module is connected to an "unsupported" 
> USB controller, the driver for which I am debugging. I thought, naturally, 
> that the bug is there. But now I am not sure. Is this really the case? If 
> yes, what might it be doing wrong? Or is it rfcomm?

is it reproducible with the latest 2.6.14-rc2 kernel running on a i386
or x86_64 system?

Regards

Marcel




-------------------------------------------------------
This SF.Net email is sponsored by:
Power Architecture Resource Center: Free content, downloads, discussions,
and more. http://solutions.newsforge.com/ibmarch.tmpl
_______________________________________________
Bluez-users mailing list
Bluez-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/bluez-users

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [2.4.30] RFCOMM race
  2005-09-29 16:38 ` [Bluez-users] " Marcel Holtmann
@ 2005-09-30 12:18   ` gl
  0 siblings, 0 replies; 3+ messages in thread
From: gl @ 2005-09-30 12:18 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: bluez-users, Maksim Krasnyanskiy, USB development list

On Thu, 29 Sep 2005, Marcel Holtmann wrote:

>> How: it forks, the child tries to connect to a non-existing peer, at this
>> time the parent issues ioctl(HCIDEVDOWN); ioctl(HCIDEVUP); the DOWN wakes
>> the child up and it dows ioctl(HCIDEVDOWN) too. That's it. On the
>> USB-analyser I see an incomplete HCI Reset, interrupted by the "Read local
>> supported features" - from the UP. (screenshot attached)
>>
>> The question is, of course, where (apart from the program) is the bug? I
>> have to say, that the bluletooth module is connected to an "unsupported"
>> USB controller, the driver for which I am debugging. I thought, naturally,
>> that the bug is there. But now I am not sure. Is this really the case? If
>> yes, what might it be doing wrong? Or is it rfcomm?
>
> is it reproducible with the latest 2.6.14-rc2 kernel running on a i386
> or x86_64 system?

Well, even worse (for me) - I cannot reproduce it on a PC with 2.4.30. 
Same with 2.6.13. So, perhaps, we should assume, that the bug indeed is in 
the USB driver. So, my question should rather be: "what can one do wrong 
in a USB driver to produce such a picture?" What should protect against 
this race? I have problems understanding the USB-log - how it can be 
produced by my program. Let's see:

Parent				Child			USB - HCI

sleep()				connect()		Create Connection
ioctl(HCIDEVDOWN) ------------>	(interrupted)
 				ioctl(HCIDEVDOWN)
ioctl(HCIDEVDOWN) (cont) <-----	(preempted)		Reset
(preempted) ------------------> (resumed:
 				DOWN sees that device
 				is already down, returns)
 				ioctl(HCIDEVUP)		Read Local Supported Features
 							(interrupts "Reset" -
 							the IN transaction
 							is missing!!!)

So, I don't understand, how it is possible - how can Reset be interrupted 
before the IN transaction is sent. The endpoint is the same. Actually, if 
you look at timestamps - the IN should long be out. It is 10ms between the 
"OUT" in "Reset" and the "Read Local Supported Features". Normally the IN 
in Reset comes less than 100us after OUT...

I am adding USB-devel to CC: Unfortunately, I cannot include a link to my 
original post with the snapshot and a code snipplet - it was too big and 
didn't get it to the list, only to the persons I included explicitely in 
CC (Bluetooth maintainers). Marcel's answer is here:
http://sourceforge.net/mailarchive/forum.php?thread_id=8348704&forum_id=1883
I can re-send the files on request.

Thanks
Guennadi
---------------------------------
Guennadi Liakhovetski, Ph.D.
DSA Daten- und Systemtechnik GmbH
Pascalstr. 28
D-52076 Aachen
Germany

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2005-09-30 12:18 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-09-29 12:25 [2.4.30] RFCOMM race gl
2005-09-29 16:38 ` [Bluez-users] " Marcel Holtmann
2005-09-30 12:18   ` gl

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