Bluetooth: Add L2CAP RFC option if ERTM is enabled
authorMarcel Holtmann <marcel@holtmann.org>
Sun, 3 May 2009 06:07:53 +0000 (23:07 -0700)
committerMarcel Holtmann <marcel@holtmann.org>
Sat, 22 Aug 2009 21:50:07 +0000 (14:50 -0700)
When trying to establish a connection with Enhanced Retransmission mode
enabled, the RFC option needs to be added to the configuration.

Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/l2cap.c

index 8a59e57..7ce1a24 100644 (file)
@@ -1743,12 +1743,29 @@ static int l2cap_build_conf_req(struct sock *sk, void *data)
 {
        struct l2cap_pinfo *pi = l2cap_pi(sk);
        struct l2cap_conf_req *req = data;
 {
        struct l2cap_pinfo *pi = l2cap_pi(sk);
        struct l2cap_conf_req *req = data;
+       struct l2cap_conf_rfc rfc = { .mode = L2CAP_MODE_BASIC };
        void *ptr = req->data;
 
        BT_DBG("sk %p", sk);
 
        void *ptr = req->data;
 
        BT_DBG("sk %p", sk);
 
-       if (pi->imtu != L2CAP_DEFAULT_MTU)
-               l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
+       switch (pi->mode) {
+       case L2CAP_MODE_BASIC:
+               if (pi->imtu != L2CAP_DEFAULT_MTU)
+                       l2cap_add_conf_opt(&ptr, L2CAP_CONF_MTU, 2, pi->imtu);
+               break;
+
+       case L2CAP_MODE_ERTM:
+               rfc.mode            = L2CAP_MODE_ERTM;
+               rfc.txwin_size      = L2CAP_DEFAULT_RX_WINDOW;
+               rfc.max_transmit    = L2CAP_DEFAULT_MAX_RECEIVE;
+               rfc.retrans_timeout = cpu_to_le16(L2CAP_DEFAULT_RETRANS_TO);
+               rfc.monitor_timeout = cpu_to_le16(L2CAP_DEFAULT_MONITOR_TO);
+               rfc.max_pdu_size    = cpu_to_le16(L2CAP_DEFAULT_MAX_RX_APDU);
+
+               l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
+                                       sizeof(rfc), (unsigned long) &rfc);
+               break;
+       }
 
        /* FIXME: Need actual value of the flush timeout */
        //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
 
        /* FIXME: Need actual value of the flush timeout */
        //if (flush_to != L2CAP_DEFAULT_FLUSH_TO)
@@ -1828,7 +1845,7 @@ static int l2cap_parse_conf_req(struct sock *sk, void *data)
                        rfc.mode = L2CAP_MODE_BASIC;
 
                        l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
                        rfc.mode = L2CAP_MODE_BASIC;
 
                        l2cap_add_conf_opt(&ptr, L2CAP_CONF_RFC,
-                                               sizeof(rfc), (unsigned long) &rfc);
+                                       sizeof(rfc), (unsigned long) &rfc);
                }
        }
 
                }
        }