Bluetooth: A2MP: Create amp_mgr global list
authorAndrei Emeltchenko <andrei.emeltchenko@intel.com>
Thu, 27 Sep 2012 14:26:07 +0000 (17:26 +0300)
committerGustavo Padovan <gustavo.padovan@collabora.co.uk>
Thu, 27 Sep 2012 20:10:03 +0000 (17:10 -0300)
Create amp_mgr_list global list which will be used by different
hci devices to find amp_mgr.

Signed-off-by: Andrei Emeltchenko <andrei.emeltchenko@intel.com>
Signed-off-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
include/net/bluetooth/a2mp.h
net/bluetooth/a2mp.c

index 6a76e0a..316c1c8 100644 (file)
 
 #define A2MP_FEAT_EXT  0x8000
 
+enum amp_mgr_state {
+       READ_LOC_AMP_INFO,
+};
+
 struct amp_mgr {
+       struct list_head        list;
        struct l2cap_conn       *l2cap_conn;
        struct l2cap_chan       *a2mp_chan;
        struct kref             kref;
        __u8                    ident;
        __u8                    handle;
+       enum amp_mgr_state      state;
        unsigned long           flags;
 };
 
@@ -118,9 +124,13 @@ struct a2mp_physlink_rsp {
 #define A2MP_STATUS_PHYS_LINK_EXISTS           0x05
 #define A2MP_STATUS_SECURITY_VIOLATION         0x06
 
+extern struct list_head amp_mgr_list;
+extern struct mutex amp_mgr_list_lock;
+
 void amp_mgr_get(struct amp_mgr *mgr);
 int amp_mgr_put(struct amp_mgr *mgr);
 struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn,
                                       struct sk_buff *skb);
+struct amp_mgr *amp_mgr_lookup_by_state(u8 state);
 
 #endif /* __A2MP_H */
index 0760d1f..3f93060 100644 (file)
 #include <net/bluetooth/l2cap.h>
 #include <net/bluetooth/a2mp.h>
 
+/* Global AMP Manager list */
+LIST_HEAD(amp_mgr_list);
+DEFINE_MUTEX(amp_mgr_list_lock);
+
 /* A2MP build & send command helper functions */
 static struct a2mp_cmd *__a2mp_build(u8 code, u8 ident, u16 len, void *data)
 {
@@ -516,6 +520,10 @@ static void amp_mgr_destroy(struct kref *kref)
 
        BT_DBG("mgr %p", mgr);
 
+       mutex_lock(&amp_mgr_list_lock);
+       list_del(&mgr->list);
+       mutex_unlock(&amp_mgr_list_lock);
+
        kfree(mgr);
 }
 
@@ -552,6 +560,10 @@ static struct amp_mgr *amp_mgr_create(struct l2cap_conn *conn)
 
        kref_init(&mgr->kref);
 
+       mutex_lock(&amp_mgr_list_lock);
+       list_add(&mgr->list, &amp_mgr_list);
+       mutex_unlock(&amp_mgr_list_lock);
+
        return mgr;
 }
 
@@ -570,3 +582,20 @@ struct l2cap_chan *a2mp_channel_create(struct l2cap_conn *conn,
 
        return mgr->a2mp_chan;
 }
+
+struct amp_mgr *amp_mgr_lookup_by_state(u8 state)
+{
+       struct amp_mgr *mgr;
+
+       mutex_lock(&amp_mgr_list_lock);
+       list_for_each_entry(mgr, &amp_mgr_list, list) {
+               if (mgr->state == state) {
+                       amp_mgr_get(mgr);
+                       mutex_unlock(&amp_mgr_list_lock);
+                       return mgr;
+               }
+       }
+       mutex_unlock(&amp_mgr_list_lock);
+
+       return NULL;
+}