Bluetooth: L2CAP: Unify code for adding and deleting channels

The code for adding and removing channels is very similar for LE and
BR/EDR so it can be unified and just leave the CID allocation up for the
bearer implementation.

Change-Id: Icf4c66262c4e973039381ebd1861fad4d46e1535
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
This commit is contained in:
Luiz Augusto von Dentz 2016-07-11 13:21:41 +03:00 committed by Johan Hedberg
commit a6a78bfbca
4 changed files with 40 additions and 35 deletions

View file

@ -49,6 +49,15 @@ extern "C" {
#include <bluetooth/buf.h>
#include <bluetooth/conn.h>
struct bt_l2cap_chan;
/** @typedef bt_l2cap_chan_destroy_t
* @brief Channel destroy callback
*
* @param chan Channel object.
*/
typedef void (*bt_l2cap_chan_destroy_t)(struct bt_l2cap_chan *chan);
/** @brief L2CAP Channel structure. */
struct bt_l2cap_chan {
/** Channel connection reference */
@ -56,7 +65,7 @@ struct bt_l2cap_chan {
/** Channel operations reference */
struct bt_l2cap_chan_ops *ops;
struct bt_l2cap_chan *_next;
void (*destroy)(struct bt_l2cap_chan *chan);
bt_l2cap_chan_destroy_t destroy;
};
/** @brief LE L2CAP Endpoint structure. */

View file

@ -167,7 +167,7 @@ __l2cap_lookup_ident(struct bt_conn *conn, uint16_t ident, bool remove)
return NULL;
}
static void l2cap_chan_del(struct bt_l2cap_chan *chan)
void bt_l2cap_chan_del(struct bt_l2cap_chan *chan)
{
BT_DBG("conn %p chan %p", chan->conn, chan);
@ -195,11 +195,23 @@ static void l2cap_rtx_timeout(struct nano_work *work)
l2cap_remove_ident(chan->chan.conn, chan->ident);
l2cap_chan_del(&chan->chan);
bt_l2cap_chan_del(&chan->chan);
}
void bt_l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan,
bt_l2cap_chan_destroy_t destroy)
{
/* Attach channel to the connection */
chan->_next = conn->channels;
conn->channels = chan;
chan->conn = conn;
chan->destroy = destroy;
BT_DBG("conn %p chan %p", conn, chan);
}
static bool l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan,
void (*destroy)(struct bt_l2cap_chan *chan))
bt_l2cap_chan_destroy_t destroy)
{
struct bt_l2cap_le_chan *ch = l2cap_chan_alloc_cid(conn, chan);
@ -208,15 +220,9 @@ static bool l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan,
return false;
}
/* Attach channel to the connection */
chan->_next = conn->channels;
conn->channels = chan;
chan->conn = conn;
chan->destroy = destroy;
nano_delayed_work_init(&ch->rtx_work, l2cap_rtx_timeout);
BT_DBG("conn %p chan %p cid 0x%04x", conn, ch, ch->rx.cid);
bt_l2cap_chan_add(conn, chan, destroy);
return true;
}
@ -270,7 +276,7 @@ void bt_l2cap_disconnected(struct bt_conn *conn)
/* prefetch since disconnected callback may cleanup */
next = chan->_next;
l2cap_chan_del(chan);
bt_l2cap_chan_del(chan);
chan = next;
}
@ -676,7 +682,7 @@ static void le_disconn_req(struct bt_l2cap *l2cap, uint8_t ident,
rsp->dcid = sys_cpu_to_le16(chan->rx.cid);
rsp->scid = sys_cpu_to_le16(chan->tx.cid);
l2cap_chan_del(&chan->chan);
bt_l2cap_chan_del(&chan->chan);
bt_l2cap_send(conn, BT_L2CAP_CID_LE_SIG, buf);
}
@ -736,7 +742,7 @@ static void le_conn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
break;
/* TODO: Retry on Authentication and Encryption errors */
default:
l2cap_chan_del(&chan->chan);
bt_l2cap_chan_del(&chan->chan);
}
}
@ -763,7 +769,7 @@ static void le_disconn_rsp(struct bt_l2cap *l2cap, uint8_t ident,
return;
}
l2cap_chan_del(&chan->chan);
bt_l2cap_chan_del(&chan->chan);
}
static void le_credits(struct bt_l2cap *l2cap, uint8_t ident,
@ -816,7 +822,7 @@ static void reject_cmd(struct bt_l2cap *l2cap, uint8_t ident,
return;
}
l2cap_chan_del(&chan->chan);
bt_l2cap_chan_del(&chan->chan);
}
#endif /* CONFIG_BLUETOOTH_L2CAP_DYNAMIC_CHANNEL */

View file

@ -151,12 +151,7 @@ static bool l2cap_br_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan)
return false;
}
/* Attach channel to the connection */
chan->_next = conn->channels;
conn->channels = chan;
chan->conn = conn;
BT_DBG("conn %p chan %p cid 0x%04x", conn, ch, ch->rx.cid);
bt_l2cap_chan_add(conn, chan, NULL);
return true;
}
@ -633,18 +628,6 @@ static void l2cap_br_send_reject(struct bt_conn *conn, uint8_t ident,
bt_l2cap_send(conn, BT_L2CAP_CID_BR_SIG, buf);
}
static void l2cap_br_chan_del(struct bt_l2cap_chan *chan)
{
BT_DBG("conn %p chan %p cid 0x%04x", chan->conn, BR_CHAN(chan),
BR_CHAN(chan)->rx.cid);
chan->conn = NULL;
if (chan->ops && chan->ops->disconnected) {
chan->ops->disconnected(chan);
}
}
static struct bt_l2cap_br_chan *l2cap_br_remove_tx_cid(struct bt_conn *conn,
uint16_t cid)
{
@ -716,7 +699,7 @@ static void l2cap_br_disconn_req(struct bt_l2cap_br *l2cap, uint8_t ident,
rsp->dcid = sys_cpu_to_le16(chan->rx.cid);
rsp->scid = sys_cpu_to_le16(chan->tx.cid);
l2cap_br_chan_del(&chan->chan);
bt_l2cap_chan_del(&chan->chan);
bt_l2cap_send(conn, BT_L2CAP_CID_BR_SIG, buf);
}

View file

@ -206,6 +206,13 @@ void bt_l2cap_connected(struct bt_conn *conn);
/* Notify L2CAP channels of a disconnect event */
void bt_l2cap_disconnected(struct bt_conn *conn);
/* Add channel to the connection */
void bt_l2cap_chan_add(struct bt_conn *conn, struct bt_l2cap_chan *chan,
bt_l2cap_chan_destroy_t destroy);
/* Delete channel */
void bt_l2cap_chan_del(struct bt_l2cap_chan *chan);
/* Notify L2CAP channels of a change in encryption state */
void bt_l2cap_encrypt_change(struct bt_conn *conn);