aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/bluetooth/a2mp.h
blob: 487b54c1308fdec26ddc48e46b4973200b45022a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
/*
   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

#include <net/bluetooth/l2cap.h>

#define A2MP_FEAT_EXT	0x8000

enum amp_mgr_state {
	READ_LOC_AMP_INFO,
	READ_LOC_AMP_ASSOC,
	READ_LOC_AMP_ASSOC_FINAL,
	WRITE_REMOTE_AMP_ASSOC,
};

struct amp_mgr {
	struct list_head	list;
	struct l2cap_conn	*l2cap_conn;
	struct l2cap_chan	*a2mp_chan;
	struct l2cap_chan	*bredr_chan;
	struct kref		kref;
	__u8			ident;
	__u8			handle;
	unsigned long		state;
	unsigned long		flags;

	struct list_head	amp_ctrls;
	struct mutex		amp_ctrls_lock;
};

struct a2mp_cmd {
	__u8	code;
	__u8	ident;
	__le16	len;
	__u8	data[0];
} __packed;

/* A2MP command codes */
#define A2MP_COMMAND_REJ         0x01
struct a2mp_cmd_rej {
	__le16	reason;
	__u8	data[0];
} __packed;

#define A2MP_DISCOVER_REQ        0x02
struct a2mp_discov_req {
	__le16	mtu;
	__le16	ext_feat;
} __packed;

struct a2mp_cl {
	__u8	id;
	__u8	type;
	__u8	status;
} __packed;

#define A2MP_DISCOVER_RSP        0x03
struct a2mp_discov_rsp {
	__le16     mtu;
	__le16     ext_feat;
	struct a2mp_cl cl[0];
} __packed;

#define A2MP_CHANGE_NOTIFY       0x04
#define A2MP_CHANGE_RSP          0x05

#define A2MP_GETINFO_REQ         0x06
struct a2mp_info_req {
	__u8       id;
} __packed;

#define A2MP_GETINFO_RSP         0x07
struct a2mp_info_rsp {
	__u8	id;
	__u8	status;
	__le32	total_bw;
	__le32	max_bw;
	__le32	min_latency;
	__le16	pal_cap;
	__le16	assoc_size;
} __packed;

#define A2MP_GETAMPASSOC_REQ     0x08
struct a2mp_amp_assoc_req {
	__u8	id;
} __packed;

#define A2MP_GETAMPASSOC_RSP     0x09
struct a2mp_amp_assoc_rsp {
	__u8	id;
	__u8	status;
	__u8	amp_assoc[0];
} __packed;

#define A2MP_CREATEPHYSLINK_REQ  0x0A
#define A2MP_DISCONNPHYSLINK_REQ 0x0C
struct a2mp_physlink_req {
	__u8	local_id;
	__u8	remote_id;
	__u8	amp_assoc[0];
} __packed;

#define A2MP_CREATEPHYSLINK_RSP  0x0B
#define A2MP_DISCONNPHYSLINK_RSP 0x0D
struct a2mp_physlink_rsp {
	__u8	local_id;
	__u8	remote_id;
	__u8	status;
} __packed;

/* A2MP response status */
#define A2MP_STATUS_SUCCESS			0x00
#define A2MP_STATUS_INVALID_CTRL_ID		0x01
#define A2MP_STATUS_UNABLE_START_LINK_CREATION	0x02
#define A2MP_STATUS_NO_PHYSICAL_LINK_EXISTS	0x02
#define A2MP_STATUS_COLLISION_OCCURED		0x03
#define A2MP_STATUS_DISCONN_REQ_RECVD		0x04
#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;

struct amp_mgr *amp_mgr_get(struct amp_mgr *mgr);
int amp_mgr_put(struct amp_mgr *mgr);
u8 __next_ident(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);
void a2mp_send(struct amp_mgr *mgr, u8 code, u8 ident, u16 len, void *data);
void a2mp_discover_amp(struct l2cap_chan *chan);
void a2mp_send_getinfo_rsp(struct hci_dev *hdev);
void a2mp_send_getampassoc_rsp(struct hci_dev *hdev, u8 status);
void a2mp_send_create_phy_link_req(struct hci_dev *hdev, u8 status);
void a2mp_send_create_phy_link_rsp(struct hci_dev *hdev, u8 status);

#endif /* __A2MP_H */