Bluetooth: bnep: Handle BNEP connection setup request
authorGrzegorz Kolodziejczyk <grzegorz.kolodziejczyk@tieto.com>
Fri, 3 Apr 2015 10:14:55 +0000 (12:14 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Fri, 3 Apr 2015 21:21:34 +0000 (23:21 +0200)
With this patch kernel will be able to handle setup request. This is
needed if we would like to handle control mesages with extension
headers. User space will be only resposible for reading setup data and
checking if scenario is conformance to specification (dst and src device
bnep role). In case of new user space, setup data must be leaved(peek
msg) on queue. New bnep session will be responsible for handling this
data.

Signed-off-by: Grzegorz Kolodziejczyk <grzegorz.kolodziejczyk@tieto.com>
Signed-off-by: Marcel Holtmann <marcel@holtmann.org>
net/bluetooth/bnep/bnep.h
net/bluetooth/bnep/core.c
net/bluetooth/bnep/sock.c

index 8709733c12a7d492301119e9ff2ced80da153f6c..40854c99bc1ecff42e8943ac506b77155ebc4fe1 100644 (file)
@@ -113,6 +113,9 @@ struct bnep_ext_hdr {
 #define BNEPGETCONNINFO        _IOR('B', 211, int)
 #define BNEPGETSUPPFEAT        _IOR('B', 212, int)
 
+#define BNEP_SETUP_RESPONSE    0
+#define BNEP_SETUP_RSP_SENT    10
+
 struct bnep_connadd_req {
        int   sock;             /* Connected socket */
        __u32 flags;
index 0ee6f6d9d93e153eaa20c7f11f70d3de6fb18b1a..1641367e54cadb461903e554c39fabf05997c9de 100644 (file)
@@ -231,7 +231,14 @@ static int bnep_rx_control(struct bnep_session *s, void *data, int len)
                break;
 
        case BNEP_SETUP_CONN_REQ:
-               err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP, BNEP_CONN_NOT_ALLOWED);
+               /* Successful response should be sent only once */
+               if (test_bit(BNEP_SETUP_RESPONSE, &s->flags) &&
+                   !test_and_set_bit(BNEP_SETUP_RSP_SENT, &s->flags))
+                       err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP,
+                                           BNEP_SUCCESS);
+               else
+                       err = bnep_send_rsp(s, BNEP_SETUP_CONN_RSP,
+                                           BNEP_CONN_NOT_ALLOWED);
                break;
 
        default: {
@@ -551,7 +558,7 @@ static struct device_type bnep_type = {
 
 int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
 {
-       u32 valid_flags = 0;
+       u32 valid_flags = BIT(BNEP_SETUP_RESPONSE);
        struct net_device *dev;
        struct bnep_session *s, *ss;
        u8 dst[ETH_ALEN], src[ETH_ALEN];
@@ -596,6 +603,7 @@ int bnep_add_connection(struct bnep_connadd_req *req, struct socket *sock)
        s->sock  = sock;
        s->role  = req->role;
        s->state = BT_CONNECTED;
+       s->flags = req->flags;
 
        s->msg.msg_flags = MSG_NOSIGNAL;
 
@@ -665,7 +673,7 @@ int bnep_del_connection(struct bnep_conndel_req *req)
 
 static void __bnep_copy_ci(struct bnep_conninfo *ci, struct bnep_session *s)
 {
-       u32 valid_flags = 0;
+       u32 valid_flags = BIT(BNEP_SETUP_RESPONSE);
 
        memset(ci, 0, sizeof(*ci));
        memcpy(ci->dst, s->eh.h_source, ETH_ALEN);
index 5766e6b66dbbe238767510edb2d27d2fd1784ec2..bde2bdd9e929e854c9e2d001a7bf9e6a364d6a2c 100644 (file)
@@ -57,7 +57,7 @@ static int bnep_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned long
        struct bnep_conninfo ci;
        struct socket *nsock;
        void __user *argp = (void __user *)arg;
-       __u32 supp_feat = 0;
+       __u32 supp_feat = BIT(BNEP_SETUP_RESPONSE);
        int err;
 
        BT_DBG("cmd %x arg %lx", cmd, arg);