Bluetooth: A2MP: Create A2MP channel
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>
Tue, 29 May 2012 10:59:01 +0000 (13:59 +0300)
committerJohan Hedberg <johan.hedberg@intel.com>
Tue, 5 Jun 2012 03:34:11 +0000 (06:34 +0300)
Create and initialize fixed A2MP channel

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
include/net/bluetooth/l2cap.h
net/bluetooth/Makefile
net/bluetooth/a2mp.c [new file with mode: 0644]
net/bluetooth/l2cap_core.c

index c5726c24ee038ff35cd115892d5ab6edfa13af62..aaba222306b68cd768149069f0f5d1ba4045628a 100644 (file)
@@ -52,6 +52,8 @@
 #define L2CAP_CONN_TIMEOUT             msecs_to_jiffies(40000)
 #define L2CAP_INFO_TIMEOUT             msecs_to_jiffies(4000)
 
+#define L2CAP_A2MP_DEFAULT_MTU         670
+
 /* L2CAP socket address */
 struct sockaddr_l2 {
        sa_family_t     l2_family;
@@ -236,6 +238,7 @@ struct l2cap_conn_rsp {
 /* channel indentifier */
 #define L2CAP_CID_SIGNALING    0x0001
 #define L2CAP_CID_CONN_LESS    0x0002
+#define L2CAP_CID_A2MP         0x0003
 #define L2CAP_CID_LE_DATA      0x0004
 #define L2CAP_CID_LE_SIGNALING 0x0005
 #define L2CAP_CID_SMP          0x0006
@@ -758,5 +761,8 @@ int l2cap_chan_send(struct l2cap_chan *chan, struct msghdr *msg, size_t len,
 void l2cap_chan_busy(struct l2cap_chan *chan, int busy);
 int l2cap_chan_check_security(struct l2cap_chan *chan);
 void l2cap_chan_set_defaults(struct l2cap_chan *chan);
+int l2cap_ertm_init(struct l2cap_chan *chan);
+void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan);
+void l2cap_chan_del(struct l2cap_chan *chan, int err);
 
 #endif /* __L2CAP_H */
index 2dc5a5700f533191558381d8bcc0b16016b185a6..fa6d94a4602a8352a6f2aa9ed13ed18ff7e6c08a 100644 (file)
@@ -9,4 +9,5 @@ obj-$(CONFIG_BT_CMTP)   += cmtp/
 obj-$(CONFIG_BT_HIDP)  += hidp/
 
 bluetooth-y := af_bluetooth.o hci_core.o hci_conn.o hci_event.o mgmt.o \
-       hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o
+       hci_sock.o hci_sysfs.o l2cap_core.o l2cap_sock.o smp.o sco.o lib.o \
+       a2mp.o
diff --git a/net/bluetooth/a2mp.c b/net/bluetooth/a2mp.c
new file mode 100644 (file)
index 0000000..de455a2
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+   Copyright (c) 2010,2011 Code Aurora Forum.  All rights reserved.
+   Copyright (c) 2011,2012 Intel Corp.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License version 2 and
+   only version 2 as published by the Free Software Foundation.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+*/
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci_core.h>
+#include <net/bluetooth/l2cap.h>
+
+static struct l2cap_ops a2mp_chan_ops = {
+       .name = "L2CAP A2MP channel",
+};
+
+static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn)
+{
+       struct l2cap_chan *chan;
+       int err;
+
+       chan = l2cap_chan_create();
+       if (!chan)
+               return NULL;
+
+       BT_DBG("chan %p", chan);
+
+       hci_conn_hold(conn->hcon);
+
+       chan->omtu = L2CAP_A2MP_DEFAULT_MTU;
+       chan->imtu = L2CAP_A2MP_DEFAULT_MTU;
+       chan->flush_to = L2CAP_DEFAULT_FLUSH_TO;
+
+       chan->ops = &a2mp_chan_ops;
+
+       l2cap_chan_set_defaults(chan);
+       chan->remote_max_tx = chan->max_tx;
+       chan->remote_tx_win = chan->tx_win;
+
+       chan->retrans_timeout = L2CAP_DEFAULT_RETRANS_TO;
+       chan->monitor_timeout = L2CAP_DEFAULT_MONITOR_TO;
+
+       skb_queue_head_init(&chan->tx_q);
+
+       chan->mode = L2CAP_MODE_ERTM;
+
+       err = l2cap_ertm_init(chan);
+       if (err < 0) {
+               l2cap_chan_del(chan, 0);
+               return NULL;
+       }
+
+       chan->conf_state = 0;
+
+       l2cap_chan_add(conn, chan);
+
+       chan->remote_mps = chan->omtu;
+       chan->mps = chan->omtu;
+
+       chan->state = BT_CONNECTED;
+
+       return chan;
+}
index 778c0c8cdc59f867eaf604c46509137b77293e22..2c616cf24c71939fd19e070a0f42f1333c065537 100644 (file)
@@ -484,14 +484,14 @@ static void __l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
        list_add(&chan->list, &conn->chan_l);
 }
 
-static void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
+void l2cap_chan_add(struct l2cap_conn *conn, struct l2cap_chan *chan)
 {
        mutex_lock(&conn->chan_lock);
        __l2cap_chan_add(conn, chan);
        mutex_unlock(&conn->chan_lock);
 }
 
-static void l2cap_chan_del(struct l2cap_chan *chan, int err)
+void l2cap_chan_del(struct l2cap_chan *chan, int err)
 {
        struct l2cap_conn *conn = chan->conn;
 
@@ -2691,7 +2691,7 @@ static void l2cap_ack_timeout(struct work_struct *work)
        l2cap_chan_put(chan);
 }
 
-static inline int l2cap_ertm_init(struct l2cap_chan *chan)
+int l2cap_ertm_init(struct l2cap_chan *chan)
 {
        int err;