blob: 15d1817fe978623a01dd80980875d1308093fbb9 [file] [log] [blame]
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07001/*
Duy Truonge833aca2013-02-12 13:35:08 -08002 Copyright (c) 2010-2012 The Linux Foundation. All rights reserved.
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -07003
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License version 2 and
6 only version 2 as published by the Free Software Foundation.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12*/
13
14#ifndef __AMP_H
15#define __AMP_H
16
17/* AMP defaults */
18
Peter Krystad101c1842011-09-22 11:00:31 -070019#define A2MP_RSP_TIMEOUT (8000) /* 8 seconds */
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070020
21/* A2MP Protocol */
22
23/* A2MP command codes */
24#define A2MP_COMMAND_REJ 0x01
25#define A2MP_DISCOVER_REQ 0x02
26#define A2MP_DISCOVER_RSP 0x03
27#define A2MP_CHANGE_NOTIFY 0x04
28#define A2MP_CHANGE_RSP 0x05
29#define A2MP_GETINFO_REQ 0x06
30#define A2MP_GETINFO_RSP 0x07
31#define A2MP_GETAMPASSOC_REQ 0x08
32#define A2MP_GETAMPASSOC_RSP 0x09
33#define A2MP_CREATEPHYSLINK_REQ 0x0A
34#define A2MP_CREATEPHYSLINK_RSP 0x0B
35#define A2MP_DISCONNPHYSLINK_REQ 0x0C
36#define A2MP_DISCONNPHYSLINK_RSP 0x0D
37
38struct a2mp_cmd_hdr {
39 __u8 code;
40 __u8 ident;
41 __le16 len;
42} __packed;
43
44struct a2mp_cmd_rej {
45 __le16 reason;
46} __packed;
47
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -070048struct a2mp_discover_req {
49 __le16 mtu;
50 __le16 ext_feat;
51} __packed;
52
53struct a2mp_cl {
54 __u8 id;
55 __u8 type;
56 __u8 status;
57} __packed;
58
59struct a2mp_discover_rsp {
60 __le16 mtu;
61 __le16 ext_feat;
62 struct a2mp_cl cl[0];
63} __packed;
64
65struct a2mp_getinfo_req {
66 __u8 id;
67} __packed;
68
69struct a2mp_getinfo_rsp {
70 __u8 id;
71 __u8 status;
72 __le32 total_bw;
73 __le32 max_bw;
74 __le32 min_latency;
75 __le16 pal_cap;
76 __le16 assoc_size;
77} __packed;
78
79struct a2mp_getampassoc_req {
80 __u8 id;
81} __packed;
82
83struct a2mp_getampassoc_rsp {
84 __u8 id;
85 __u8 status;
86 __u8 amp_assoc[0];
87} __packed;
88
89struct a2mp_createphyslink_req {
90 __u8 local_id;
91 __u8 remote_id;
92 __u8 amp_assoc[0];
93} __packed;
94
95struct a2mp_createphyslink_rsp {
96 __u8 local_id;
97 __u8 remote_id;
98 __u8 status;
99} __packed;
100
101struct a2mp_disconnphyslink_req {
102 __u8 local_id;
103 __u8 remote_id;
104} __packed;
105
106struct a2mp_disconnphyslink_rsp {
107 __u8 local_id;
108 __u8 remote_id;
109 __u8 status;
110} __packed;
111
112
113/* L2CAP-AMP module interface */
114int amp_init(void);
115void amp_exit(void);
116
117/* L2CAP-AMP fixed channel interface */
Peter Krystad072a51f2012-03-30 12:59:33 -0700118void amp_conn_ind(struct hci_conn *hcon, struct sk_buff *skb);
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700119
120/* L2CAP-AMP link interface */
121void amp_create_physical(struct l2cap_conn *conn, struct sock *sk);
122void amp_accept_physical(struct l2cap_conn *conn, u8 id, struct sock *sk);
123
124/* AMP manager internals */
125struct amp_ctrl {
126 struct amp_mgr *mgr;
127 __u8 id;
128 __u8 type;
129 __u8 status;
130 __u32 total_bw;
131 __u32 max_bw;
132 __u32 min_latency;
133 __u16 pal_cap;
134 __u16 max_assoc_size;
135};
136
137struct amp_mgr {
138 struct list_head list;
139 __u8 discovered;
140 __u8 next_ident;
141 struct l2cap_conn *l2cap_conn;
142 struct socket *a2mp_sock;
143 struct list_head ctx_list;
144 rwlock_t ctx_list_lock;
145 struct amp_ctrl *ctrls; /* @@ TODO s.b. list of controllers */
146 struct sk_buff *skb;
147 __u8 connected;
148};
149
150/* AMP Manager signalling contexts */
151#define AMP_GETAMPASSOC 1
152#define AMP_CREATEPHYSLINK 2
153#define AMP_ACCEPTPHYSLINK 3
154#define AMP_CREATELOGLINK 4
155#define AMP_ACCEPTLOGLINK 5
156
157/* Get AMP Assoc sequence */
158#define AMP_GAA_INIT 0
159#define AMP_GAA_RLAA_COMPLETE 1
160struct amp_gaa_state {
161 __u8 req_ident;
162 __u16 len_so_far;
163 __u8 *assoc;
164};
165
166/* Create Physical Link sequence */
167#define AMP_CPL_INIT 0
168#define AMP_CPL_DISC_RSP 1
169#define AMP_CPL_GETINFO_RSP 2
170#define AMP_CPL_GAA_RSP 3
171#define AMP_CPL_CPL_STATUS 4
172#define AMP_CPL_WRA_COMPLETE 5
173#define AMP_CPL_CHANNEL_SELECT 6
174#define AMP_CPL_RLA_COMPLETE 7
175#define AMP_CPL_PL_COMPLETE 8
176#define AMP_CPL_PL_CANCEL 9
177struct amp_cpl_state {
178 __u8 remote_id;
179 __u16 max_len;
180 __u8 *remote_assoc;
181 __u8 *local_assoc;
182 __u16 len_so_far;
183 __u16 rem_len;
184 __u8 phy_handle;
185};
186
187/* Accept Physical Link sequence */
188#define AMP_APL_INIT 0
189#define AMP_APL_APL_STATUS 1
190#define AMP_APL_WRA_COMPLETE 2
191#define AMP_APL_PL_COMPLETE 3
192struct amp_apl_state {
193 __u8 remote_id;
194 __u8 req_ident;
195 __u8 *remote_assoc;
196 __u16 len_so_far;
197 __u16 rem_len;
198 __u8 phy_handle;
199};
200
201/* Create/Accept Logical Link sequence */
202#define AMP_LOG_INIT 0
203#define AMP_LOG_LL_STATUS 1
204#define AMP_LOG_LL_COMPLETE 2
205struct amp_log_state {
206 __u8 remote_id;
207};
208
209/* Possible event types a context may wait for */
210#define AMP_INIT 0x01
211#define AMP_HCI_EVENT 0x02
212#define AMP_HCI_CMD_CMPLT 0x04
213#define AMP_HCI_CMD_STATUS 0x08
214#define AMP_A2MP_RSP 0x10
215#define AMP_KILLED 0x20
216#define AMP_CANCEL 0x40
217struct amp_ctx {
218 struct list_head list;
219 struct amp_mgr *mgr;
220 struct hci_dev *hdev;
221 __u8 type;
222 __u8 state;
223 union {
224 struct amp_gaa_state gaa;
225 struct amp_cpl_state cpl;
226 struct amp_apl_state apl;
227 } d;
228 __u8 evt_type;
229 __u8 evt_code;
230 __u16 opcode;
231 __u8 id;
232 __u8 rsp_ident;
233
234 struct sock *sk;
235 struct amp_ctx *deferred;
236 struct timer_list timer;
237};
238
239/* AMP work */
240struct amp_work_pl_timeout {
241 struct work_struct work;
242 struct amp_ctrl *ctrl;
243};
244struct amp_work_ctx_timeout {
245 struct work_struct work;
246 struct amp_ctx *ctx;
247};
248struct amp_work_data_ready {
249 struct work_struct work;
250 struct sock *sk;
251 int bytes;
252};
253struct amp_work_state_change {
254 struct work_struct work;
255 struct sock *sk;
256};
257struct amp_work_conn_ind {
258 struct work_struct work;
Peter Krystad072a51f2012-03-30 12:59:33 -0700259 struct hci_conn *hcon;
Bryan Huntsman3f2bc4d2011-08-16 17:27:22 -0700260 struct sk_buff *skb;
261};
262struct amp_work_create_physical {
263 struct work_struct work;
264 struct l2cap_conn *conn;
265 u8 id;
266 struct sock *sk;
267};
268struct amp_work_accept_physical {
269 struct work_struct work;
270 struct l2cap_conn *conn;
271 u8 id;
272 struct sock *sk;
273};
274struct amp_work_cmd_cmplt {
275 struct work_struct work;
276 struct hci_dev *hdev;
277 u16 opcode;
278 struct sk_buff *skb;
279};
280struct amp_work_cmd_status {
281 struct work_struct work;
282 struct hci_dev *hdev;
283 u16 opcode;
284 u8 status;
285};
286struct amp_work_event {
287 struct work_struct work;
288 struct hci_dev *hdev;
289 u8 event;
290 struct sk_buff *skb;
291};
292
293#endif /* __AMP_H */