Commit 9740e49d authored by Andrei Emeltchenko's avatar Andrei Emeltchenko Committed by Johan Hedberg
Browse files

Bluetooth: A2MP: AMP Manager basic functions



Define AMP Manager and some basic functions.

Signed-off-by: default avatarAndrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
parent 466f8004
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
/*
   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.
*/

#ifndef __A2MP_H
#define __A2MP_H

struct amp_mgr {
	struct l2cap_conn	*l2cap_conn;
	struct l2cap_chan	*a2mp_chan;
	struct kref		kref;
	__u8			ident;
	__u8			handle;
	unsigned long		flags;
};

void amp_mgr_get(struct amp_mgr *mgr);
int amp_mgr_put(struct amp_mgr *mgr);

#endif /* __A2MP_H */
+1 −0
Original line number Diff line number Diff line
@@ -332,6 +332,7 @@ struct hci_conn {
	void		*l2cap_data;
	void		*sco_data;
	void		*smp_conn;
	struct amp_mgr	*amp_mgr;

	struct hci_conn	*link;

+54 −0
Original line number Diff line number Diff line
@@ -15,6 +15,7 @@
#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/l2cap.h>
#include <net/bluetooth/a2mp.h>

static struct l2cap_ops a2mp_chan_ops = {
	.name = "L2CAP A2MP channel",
@@ -67,3 +68,56 @@ static struct l2cap_chan *a2mp_chan_open(struct l2cap_conn *conn)

	return chan;
}

/* AMP Manager functions */
void amp_mgr_get(struct amp_mgr *mgr)
{
	BT_DBG("mgr %p", mgr);

	kref_get(&mgr->kref);
}

static void amp_mgr_destroy(struct kref *kref)
{
	struct amp_mgr *mgr = container_of(kref, struct amp_mgr, kref);

	BT_DBG("mgr %p", mgr);

	kfree(mgr);
}

int amp_mgr_put(struct amp_mgr *mgr)
{
	BT_DBG("mgr %p", mgr);

	return kref_put(&mgr->kref, &amp_mgr_destroy);
}

static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn)
{
	struct amp_mgr *mgr;
	struct l2cap_chan *chan;

	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
	if (!mgr)
		return NULL;

	BT_DBG("conn %p mgr %p", conn, mgr);

	mgr->l2cap_conn = conn;

	chan = a2mp_chan_open(conn);
	if (!chan) {
		kfree(mgr);
		return NULL;
	}

	mgr->a2mp_chan = chan;
	chan->data = mgr;

	conn->hcon->amp_mgr = mgr;

	kref_init(&mgr->kref);

	return mgr;
}
+4 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@

#include <net/bluetooth/bluetooth.h>
#include <net/bluetooth/hci_core.h>
#include <net/bluetooth/a2mp.h>

static void hci_le_connect(struct hci_conn *conn)
{
@@ -411,6 +412,9 @@ int hci_conn_del(struct hci_conn *conn)

	hci_chan_list_flush(conn);

	if (conn->amp_mgr)
		amp_mgr_put(conn->amp_mgr);

	hci_conn_hash_del(hdev, conn);
	if (hdev->notify)
		hdev->notify(hdev, HCI_NOTIFY_CONN_DEL);