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

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