26 plen =
sizeof(*cmd) +
len;
40 static void a2mp_send(
struct amp_mgr *mgr,
u8 code,
u8 ident,
u16 len,
49 cmd = __a2mp_build(code, ident, len, data);
66 static inline void __a2mp_cl_bredr(
struct a2mp_cl *
cl)
112 static int a2mp_discover_req(
struct amp_mgr *mgr,
struct sk_buff *skb,
121 if (len <
sizeof(*req))
132 if (len <
sizeof(ext_feat))
135 ext_feat = get_unaligned_le16(skb->
data);
136 BT_DBG(
"efm 0x%4.4x", ext_feat);
143 num_ctrl = __hci_num_ctrl();
154 __a2mp_add_cl(mgr, rsp->cl, num_ctrl);
164 static int a2mp_change_notify(
struct amp_mgr *mgr,
struct sk_buff *skb,
169 while (skb->
len >=
sizeof(*cl)) {
170 BT_DBG(
"Controller id %d type %d status %d", cl->
id, cl->
type,
180 static int a2mp_getinfo_req(
struct amp_mgr *mgr,
struct sk_buff *skb,
214 static int a2mp_getampassoc_req(
struct amp_mgr *mgr,
struct sk_buff *skb,
246 static int a2mp_createphyslink_req(
struct amp_mgr *mgr,
struct sk_buff *skb,
283 static int a2mp_discphyslink_req(
struct amp_mgr *mgr,
struct sk_buff *skb,
316 static inline int a2mp_cmd_rsp(
struct amp_mgr *mgr,
struct sk_buff *skb,
334 while (skb->
len >=
sizeof(*hdr)) {
337 hdr = (
void *) skb->
data;
344 if (len > skb->
len || !hdr->
ident) {
353 a2mp_command_rej(mgr, skb, hdr);
357 err = a2mp_discover_req(mgr, skb, hdr);
361 err = a2mp_change_notify(mgr, skb, hdr);
365 err = a2mp_getinfo_req(mgr, skb, hdr);
369 err = a2mp_getampassoc_req(mgr, skb, hdr);
373 err = a2mp_createphyslink_req(mgr, skb, hdr);
377 err = a2mp_discphyslink_req(mgr, skb, hdr);
386 err = a2mp_cmd_rsp(mgr, skb, hdr);
390 BT_ERR(
"Unknown A2MP sig cmd 0x%2.2x", hdr->
code);
400 hdr = (
void *) skb->
data;
402 BT_DBG(
"Send A2MP Rej: cmd 0x%2.2x err %d", hdr->
code, err);
417 static void a2mp_chan_close_cb(
struct l2cap_chan *chan)
422 static void a2mp_chan_state_change_cb(
struct l2cap_chan *chan,
int state)
429 BT_DBG(
"chan %p state %s", chan, state_to_string(state));
442 unsigned long len,
int nb)
447 static struct l2cap_ops a2mp_chan_ops = {
448 .name =
"L2CAP A2MP channel",
449 .recv = a2mp_chan_recv_cb,
450 .close = a2mp_chan_close_cb,
451 .state_change = a2mp_chan_state_change_cb,
452 .alloc_skb = a2mp_chan_alloc_skb_cb,
455 .new_connection = l2cap_chan_no_new_connection,
456 .teardown = l2cap_chan_no_teardown,
457 .ready = l2cap_chan_no_ready,
474 chan->
ops = &a2mp_chan_ops;
483 skb_queue_head_init(&chan->
tx_q);
510 kref_get(&mgr->
kref);
513 static void amp_mgr_destroy(
struct kref *
kref)
526 return kref_put(&mgr->
kref, &_mgr_destroy);
538 BT_DBG(
"conn %p mgr %p", conn, mgr);
542 chan = a2mp_chan_open(conn);
551 conn->
hcon->amp_mgr = mgr;
553 kref_init(&mgr->
kref);
563 mgr = amp_mgr_create(conn);
565 BT_ERR(
"Could not create AMP manager");