Return-Path: MIME-Version: 1.0 Date: Wed, 7 Jan 2009 13:35:58 -0800 Message-ID: Subject: Setting TIOCM_CD and TIOCM_RI in rfcomm (i.e. acting like a DCE) From: Adam Bliss To: linux-bluetooth@vger.kernel.org Content-Type: text/plain; charset=ISO-8859-1 Sender: linux-bluetooth-owner@vger.kernel.org List-ID: Hi there, I apologize if I am mailing the wrong list; I saw the address posted on bluez.org. I would like to set the CD (Carrier Detect) and RI (Ring Indicator) signals on an rfcomm line. I understand that these are typically DCE -> DTE signals, but in rfcomm there doesn't seem to be much meaning to this distinction. My use case is a linux box with a bluetooth adapter, talking to a BGB203. Now I see in the rfcomm driver that that tiocmset() should be able to handle these signals: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=net/bluetooth/rfcomm/tty.c;hb=09c7d8293a2d1317d16ef4ddb9f6dd2553d0694e 1019 static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsigned int set, unsigned int clear) ... 1033 if (set & TIOCM_RI) 1034 v24_sig |= RFCOMM_V24_IC; 1035 if (set & TIOCM_CD) 1036 v24_sig |= RFCOMM_V24_DV; ... So I tried to write code like this: fd = open("/dev/rfcomm1", O_RDWR | O_NDELAY); ri = TIOCM_RI; ioctl(fd, TIOCMSET, &ri); But it doesn't work. (I'm fully able to connect the rfcomm link and pass characters over it. Moreover, I can control the DTR signal in this manner. But not RI or CD.) I recompiled the net/bluetooth/rfcomm.ko driver with BT_DBG turned on, tried setting ri to 0xffff, and saw this: rfcomm_tty_tiocmset: tty d25bc800 dev c34369c0 set 0xe006 clear 0x00 This mask is conspicuously missing the RI and CD bits (0x40 and 0x80). This behavior seems to come from the tty driver: http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob;f=drivers/char/tty_io.c;h=d33e5ab061779a67e63b305b30b29d01f6fe38ca;hb=HEAD ... 2452 static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, 2453 unsigned __user *p) ... 2477 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; 2478 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; 2479 return tty->ops->tiocmset(tty, file, set, clear); (The mask on line 2477 comes out to 0xe006.) I don't know the purpose of these lines, but they seem to imply that it is impossible to set the RI and CD signals using tiocmset() an rfcomm device. To test my theory, I tried out this patch against my 2.6.22 kernel: --- net/bluetooth/rfcomm/tty.c 2009-01-07 10:06:50.000000000 +0000 +++ net/bluetooth/rfcomm/tty.c~ 2009-01-07 10:05:40.000000000 +0000 @@ -1030,18 +1006,18 @@ v24_sig |= RFCOMM_V24_RTC; if (set & TIOCM_RTS || set & TIOCM_CTS) v24_sig |= RFCOMM_V24_RTR; - if (set & TIOCM_RI) + if (set & TIOCM_OUT1) v24_sig |= RFCOMM_V24_IC; - if (set & TIOCM_CD) + if (set & TIOCM_OUT2) v24_sig |= RFCOMM_V24_DV; I then changed my code snippet to use TIOCM_OUT1 instead of TIOCM_RI. It worked perfectly, setting the Ring Indicator signal on the rfcomm link, which was reflected on my BGB203. Is there any way to set RI and CD using the stock rfcomm driver? If not, should something be changed either in net/bluetooth/rfcomm/tty.c or in drivers/char/tty_io.c ? I don't know the purpose of TIOCM_OUT1 / TIOCM_OUT2, but they do not seem to be used elsewhere in rfcomm, so perhaps this remapping won't hurt anything. (If anyone has a suggestion for a simple fix, I would be happy to try to submit a patch, but it would be my first.) Thanks, --Adam Bliss