aboutsummaryrefslogtreecommitdiffstats
path: root/net/bluetooth/rfcomm/tty.c
diff options
context:
space:
mode:
authorJ. Suter <jsuter@hardwave.de>2005-08-09 23:28:46 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2005-08-29 18:55:03 -0400
commit3a5e903c09aed19ca4a1bb26d87b8d6461a93818 (patch)
treeb9761b89aaba6537d06893091a2f43c9a8e17c3f /net/bluetooth/rfcomm/tty.c
parent7b9eb9e2099f6f4acd6a36bcd7820d27c3cf5ee3 (diff)
[Bluetooth]: Implement RFCOMM remote port negotiation
This patch implements the remote port negotiation (RPN) of the RFCOMM protocol for Bluetooth. Signed-off-by: J. Suter <jsuter@hardwave.de> Signed-off-by: Marcel Holtmann <marcel@holtmann.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bluetooth/rfcomm/tty.c')
-rw-r--r--net/bluetooth/rfcomm/tty.c197
1 files changed, 160 insertions, 37 deletions
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c
index 67d9dd6b0fac..bbc3a44a86f0 100644
--- a/net/bluetooth/rfcomm/tty.c
+++ b/net/bluetooth/rfcomm/tty.c
@@ -745,20 +745,143 @@ static int rfcomm_tty_ioctl(struct tty_struct *tty, struct file *filp, unsigned
745 return -ENOIOCTLCMD; 745 return -ENOIOCTLCMD;
746} 746}
747 747
748#define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
749
750static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old) 748static void rfcomm_tty_set_termios(struct tty_struct *tty, struct termios *old)
751{ 749{
752 BT_DBG("tty %p", tty); 750 struct termios *new = (struct termios *) tty->termios;
751 int old_baud_rate = tty_termios_baud_rate(old);
752 int new_baud_rate = tty_termios_baud_rate(new);
753 753
754 if ((tty->termios->c_cflag == old->c_cflag) && 754 u8 baud, data_bits, stop_bits, parity, x_on, x_off;
755 (RELEVANT_IFLAG(tty->termios->c_iflag) == RELEVANT_IFLAG(old->c_iflag))) 755 u16 changes = 0;
756 return; 756
757 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
758
759 BT_DBG("tty %p termios %p", tty, old);
760
761 /* Handle turning off CRTSCTS */
762 if ((old->c_cflag & CRTSCTS) && !(new->c_cflag & CRTSCTS))
763 BT_DBG("Turning off CRTSCTS unsupported");
764
765 /* Parity on/off and when on, odd/even */
766 if (((old->c_cflag & PARENB) != (new->c_cflag & PARENB)) ||
767 ((old->c_cflag & PARODD) != (new->c_cflag & PARODD)) ) {
768 changes |= RFCOMM_RPN_PM_PARITY;
769 BT_DBG("Parity change detected.");
770 }
771
772 /* Mark and space parity are not supported! */
773 if (new->c_cflag & PARENB) {
774 if (new->c_cflag & PARODD) {
775 BT_DBG("Parity is ODD");
776 parity = RFCOMM_RPN_PARITY_ODD;
777 } else {
778 BT_DBG("Parity is EVEN");
779 parity = RFCOMM_RPN_PARITY_EVEN;
780 }
781 } else {
782 BT_DBG("Parity is OFF");
783 parity = RFCOMM_RPN_PARITY_NONE;
784 }
785
786 /* Setting the x_on / x_off characters */
787 if (old->c_cc[VSTOP] != new->c_cc[VSTOP]) {
788 BT_DBG("XOFF custom");
789 x_on = new->c_cc[VSTOP];
790 changes |= RFCOMM_RPN_PM_XON;
791 } else {
792 BT_DBG("XOFF default");
793 x_on = RFCOMM_RPN_XON_CHAR;
794 }
795
796 if (old->c_cc[VSTART] != new->c_cc[VSTART]) {
797 BT_DBG("XON custom");
798 x_off = new->c_cc[VSTART];
799 changes |= RFCOMM_RPN_PM_XOFF;
800 } else {
801 BT_DBG("XON default");
802 x_off = RFCOMM_RPN_XOFF_CHAR;
803 }
804
805 /* Handle setting of stop bits */
806 if ((old->c_cflag & CSTOPB) != (new->c_cflag & CSTOPB))
807 changes |= RFCOMM_RPN_PM_STOP;
808
809 /* POSIX does not support 1.5 stop bits and RFCOMM does not
810 * support 2 stop bits. So a request for 2 stop bits gets
811 * translated to 1.5 stop bits */
812 if (new->c_cflag & CSTOPB) {
813 stop_bits = RFCOMM_RPN_STOP_15;
814 } else {
815 stop_bits = RFCOMM_RPN_STOP_1;
816 }
757 817
758 /* handle turning off CRTSCTS */ 818 /* Handle number of data bits [5-8] */
759 if ((old->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) { 819 if ((old->c_cflag & CSIZE) != (new->c_cflag & CSIZE))
760 BT_DBG("turning off CRTSCTS"); 820 changes |= RFCOMM_RPN_PM_DATA;
821
822 switch (new->c_cflag & CSIZE) {
823 case CS5:
824 data_bits = RFCOMM_RPN_DATA_5;
825 break;
826 case CS6:
827 data_bits = RFCOMM_RPN_DATA_6;
828 break;
829 case CS7:
830 data_bits = RFCOMM_RPN_DATA_7;
831 break;
832 case CS8:
833 data_bits = RFCOMM_RPN_DATA_8;
834 break;
835 default:
836 data_bits = RFCOMM_RPN_DATA_8;
837 break;
761 } 838 }
839
840 /* Handle baudrate settings */
841 if (old_baud_rate != new_baud_rate)
842 changes |= RFCOMM_RPN_PM_BITRATE;
843
844 switch (new_baud_rate) {
845 case 2400:
846 baud = RFCOMM_RPN_BR_2400;
847 break;
848 case 4800:
849 baud = RFCOMM_RPN_BR_4800;
850 break;
851 case 7200:
852 baud = RFCOMM_RPN_BR_7200;
853 break;
854 case 9600:
855 baud = RFCOMM_RPN_BR_9600;
856 break;
857 case 19200:
858 baud = RFCOMM_RPN_BR_19200;
859 break;
860 case 38400:
861 baud = RFCOMM_RPN_BR_38400;
862 break;
863 case 57600:
864 baud = RFCOMM_RPN_BR_57600;
865 break;
866 case 115200:
867 baud = RFCOMM_RPN_BR_115200;
868 break;
869 case 230400:
870 baud = RFCOMM_RPN_BR_230400;
871 break;
872 default:
873 /* 9600 is standard accordinag to the RFCOMM specification */
874 baud = RFCOMM_RPN_BR_9600;
875 break;
876
877 }
878
879 if (changes)
880 rfcomm_send_rpn(dev->dlc->session, 1, dev->dlc->dlci, baud,
881 data_bits, stop_bits, parity,
882 RFCOMM_RPN_FLOW_NONE, x_on, x_off, changes);
883
884 return;
762} 885}
763 886
764static void rfcomm_tty_throttle(struct tty_struct *tty) 887static void rfcomm_tty_throttle(struct tty_struct *tty)
@@ -766,7 +889,7 @@ static void rfcomm_tty_throttle(struct tty_struct *tty)
766 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; 889 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
767 890
768 BT_DBG("tty %p dev %p", tty, dev); 891 BT_DBG("tty %p dev %p", tty, dev);
769 892
770 rfcomm_dlc_throttle(dev->dlc); 893 rfcomm_dlc_throttle(dev->dlc);
771} 894}
772 895
@@ -775,7 +898,7 @@ static void rfcomm_tty_unthrottle(struct tty_struct *tty)
775 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; 898 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
776 899
777 BT_DBG("tty %p dev %p", tty, dev); 900 BT_DBG("tty %p dev %p", tty, dev);
778 901
779 rfcomm_dlc_unthrottle(dev->dlc); 902 rfcomm_dlc_unthrottle(dev->dlc);
780} 903}
781 904
@@ -846,35 +969,35 @@ static int rfcomm_tty_tiocmget(struct tty_struct *tty, struct file *filp)
846 969
847static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsigned int set, unsigned int clear) 970static int rfcomm_tty_tiocmset(struct tty_struct *tty, struct file *filp, unsigned int set, unsigned int clear)
848{ 971{
849 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data; 972 struct rfcomm_dev *dev = (struct rfcomm_dev *) tty->driver_data;
850 struct rfcomm_dlc *dlc = dev->dlc; 973 struct rfcomm_dlc *dlc = dev->dlc;
851 u8 v24_sig; 974 u8 v24_sig;
852 975
853 BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear); 976 BT_DBG("tty %p dev %p set 0x%02x clear 0x%02x", tty, dev, set, clear);
854 977
855 rfcomm_dlc_get_modem_status(dlc, &v24_sig); 978 rfcomm_dlc_get_modem_status(dlc, &v24_sig);
856 979
857 if (set & TIOCM_DSR || set & TIOCM_DTR) 980 if (set & TIOCM_DSR || set & TIOCM_DTR)
858 v24_sig |= RFCOMM_V24_RTC; 981 v24_sig |= RFCOMM_V24_RTC;
859 if (set & TIOCM_RTS || set & TIOCM_CTS) 982 if (set & TIOCM_RTS || set & TIOCM_CTS)
860 v24_sig |= RFCOMM_V24_RTR; 983 v24_sig |= RFCOMM_V24_RTR;
861 if (set & TIOCM_RI) 984 if (set & TIOCM_RI)
862 v24_sig |= RFCOMM_V24_IC; 985 v24_sig |= RFCOMM_V24_IC;
863 if (set & TIOCM_CD) 986 if (set & TIOCM_CD)
864 v24_sig |= RFCOMM_V24_DV; 987 v24_sig |= RFCOMM_V24_DV;
865 988
866 if (clear & TIOCM_DSR || clear & TIOCM_DTR) 989 if (clear & TIOCM_DSR || clear & TIOCM_DTR)
867 v24_sig &= ~RFCOMM_V24_RTC; 990 v24_sig &= ~RFCOMM_V24_RTC;
868 if (clear & TIOCM_RTS || clear & TIOCM_CTS) 991 if (clear & TIOCM_RTS || clear & TIOCM_CTS)
869 v24_sig &= ~RFCOMM_V24_RTR; 992 v24_sig &= ~RFCOMM_V24_RTR;
870 if (clear & TIOCM_RI) 993 if (clear & TIOCM_RI)
871 v24_sig &= ~RFCOMM_V24_IC; 994 v24_sig &= ~RFCOMM_V24_IC;
872 if (clear & TIOCM_CD) 995 if (clear & TIOCM_CD)
873 v24_sig &= ~RFCOMM_V24_DV; 996 v24_sig &= ~RFCOMM_V24_DV;
874 997
875 rfcomm_dlc_set_modem_status(dlc, v24_sig); 998 rfcomm_dlc_set_modem_status(dlc, v24_sig);
876 999
877 return 0; 1000 return 0;
878} 1001}
879 1002
880/* ---- TTY structure ---- */ 1003/* ---- TTY structure ---- */