1289284Srpaulo/*
2289284Srpaulo * FST module - interface definitions
3289284Srpaulo * Copyright (c) 2014, Qualcomm Atheros, Inc.
4289284Srpaulo *
5289284Srpaulo * This software may be distributed under the terms of the BSD license.
6289284Srpaulo * See README for more details.
7289284Srpaulo */
8289284Srpaulo
9289284Srpaulo#ifndef FST_H
10289284Srpaulo#define FST_H
11289284Srpaulo
12289284Srpaulo#ifdef CONFIG_FST
13289284Srpaulo
14289284Srpaulo#include "common/defs.h"
15289284Srpaulo#include "fst/fst_ctrl_iface.h"
16289284Srpaulo
17289284Srpaulo/* FST module hostap integration API */
18289284Srpaulo
19289284Srpaulo#define US_IN_MS           1000
20289284Srpaulo#define LLT_UNIT_US        32 /* See 10.32.2.2  Transitioning between states */
21289284Srpaulo
22346981Scy/*
23346981Scy * These were originally
24346981Scy * #define FST_LLT_MS_TO_VAL(m) (((u32) (m)) * US_IN_MS / LLT_UNIT_US)
25346981Scy * #define FST_LLT_VAL_TO_MS(v) (((u32) (v)) * LLT_UNIT_US / US_IN_MS)
26346981Scy * #define FST_MAX_LLT_MS FST_LLT_VAL_TO_MS(-1)
27346981Scy * but those can overflow 32-bit unsigned integer, so use alternative defines
28346981Scy * to avoid undefined behavior with such overflow.
29346981Scy * LLT_UNIT_US/US_IN_MS = 32/1000 = 4/125
30346981Scy */
31346981Scy#define FST_LLT_MS_TO_VAL(m) (((u32) (m)) * 125 / 4)
32346981Scy#define FST_LLT_VAL_TO_MS(v) (((u32) (v)) * 4 / 125)
33346981Scy#define FST_MAX_LLT_MS       (((u32) -1) / 4)
34289284Srpaulo#define FST_MAX_PRIO_VALUE   ((u8) -1)
35289284Srpaulo#define FST_MAX_GROUP_ID_LEN IFNAMSIZ
36289284Srpaulo
37289284Srpaulo#define FST_DEFAULT_LLT_CFG_VALUE 50
38289284Srpaulo
39289284Srpaulostruct hostapd_hw_modes;
40289284Srpaulostruct ieee80211_mgmt;
41289284Srpaulostruct fst_iface;
42289284Srpaulostruct fst_group;
43289284Srpaulostruct fst_session;
44289284Srpaulostruct fst_get_peer_ctx;
45289284Srpaulostruct fst_ctrl_handle;
46289284Srpaulo
47289284Srpaulostruct fst_wpa_obj {
48289284Srpaulo	void *ctx;
49289284Srpaulo
50289284Srpaulo	/**
51289284Srpaulo	 * get_bssid - Get BSSID of the interface
52289284Srpaulo	 * @ctx: User context %ctx
53289284Srpaulo	 * Returns: BSSID for success, %NULL for failure.
54289284Srpaulo	 *
55289284Srpaulo	 * NOTE: For AP it returns the own BSSID, while for STA - the BSSID of
56289284Srpaulo	 * the associated AP.
57289284Srpaulo	 */
58289284Srpaulo	const u8 * (*get_bssid)(void *ctx);
59289284Srpaulo
60289284Srpaulo	/**
61289284Srpaulo	 * get_channel_info - Get current channel info
62289284Srpaulo	 * @ctx: User context %ctx
63289284Srpaulo	 * @hw_mode: OUT, current HW mode
64289284Srpaulo	 * @channel: OUT, current channel
65289284Srpaulo	 */
66289284Srpaulo	void (*get_channel_info)(void *ctx, enum hostapd_hw_mode *hw_mode,
67289284Srpaulo				 u8 *channel);
68289284Srpaulo
69289284Srpaulo	/**
70289284Srpaulo	 * get_hw_modes - Get hardware modes
71289284Srpaulo	 * @ctx: User context %ctx
72289284Srpaulo	 * @modes: OUT, pointer on array of hw modes
73289284Srpaulo	 *
74289284Srpaulo	 * Returns: Number of hw modes available.
75289284Srpaulo	 */
76289284Srpaulo	int (*get_hw_modes)(void *ctx, struct hostapd_hw_modes **modes);
77289284Srpaulo
78289284Srpaulo	/**
79289284Srpaulo	 * set_ies - Set interface's MB IE
80289284Srpaulo	 * @ctx: User context %ctx
81289284Srpaulo	 * @fst_ies: MB IE buffer (owned by FST module)
82289284Srpaulo	 */
83289284Srpaulo	void (*set_ies)(void *ctx, const struct wpabuf *fst_ies);
84289284Srpaulo
85289284Srpaulo	/**
86289284Srpaulo	 * send_action - Send FST Action frame via the interface
87289284Srpaulo	 * @ctx: User context %ctx
88289284Srpaulo	 * @addr: Address of the destination STA
89289284Srpaulo	 * @data: Action frame buffer
90289284Srpaulo	 * Returns: 0 for success, negative error code for failure.
91289284Srpaulo	 */
92289284Srpaulo	int (*send_action)(void *ctx, const u8 *addr, struct wpabuf *data);
93289284Srpaulo
94289284Srpaulo	/**
95289284Srpaulo	 * get_mb_ie - Get last MB IE received from STA
96289284Srpaulo	 * @ctx: User context %ctx
97289284Srpaulo	 * @addr: Address of the STA
98289284Srpaulo	 * Returns: MB IE buffer, %NULL if no MB IE received from the STA
99289284Srpaulo	 */
100289284Srpaulo	const struct wpabuf * (*get_mb_ie)(void *ctx, const u8 *addr);
101289284Srpaulo
102289284Srpaulo	/**
103289284Srpaulo	 * update_mb_ie - Update last MB IE received from STA
104289284Srpaulo	 * @ctx: User context %ctx
105289284Srpaulo	 * @addr: Address of the STA
106289284Srpaulo	 * @buf: Buffer that contains the MB IEs data
107289284Srpaulo	 * @size: Size of data in %buf
108289284Srpaulo	 */
109289284Srpaulo	void (*update_mb_ie)(void *ctx, const u8 *addr,
110289284Srpaulo			     const u8 *buf, size_t size);
111289284Srpaulo
112289284Srpaulo	/**
113289284Srpaulo	 * get_peer_first - Get MAC address of the 1st connected STA
114289284Srpaulo	 * @ctx: User context %ctx
115289284Srpaulo	 * @get_ctx: Context to be used for %get_peer_next call
116289284Srpaulo	 * @mb_only: %TRUE if only multi-band capable peer should be reported
117289284Srpaulo	 * Returns: Address of the 1st connected STA, %NULL if no STAs connected
118289284Srpaulo	 */
119289284Srpaulo	const u8 * (*get_peer_first)(void *ctx,
120289284Srpaulo				     struct fst_get_peer_ctx **get_ctx,
121289284Srpaulo				     Boolean mb_only);
122289284Srpaulo	/**
123289284Srpaulo	 * get_peer_next - Get MAC address of the next connected STA
124289284Srpaulo	 * @ctx: User context %ctx
125289284Srpaulo	 * @get_ctx: Context received from %get_peer_first or previous
126289284Srpaulo	 *           %get_peer_next call
127289284Srpaulo	 * @mb_only: %TRUE if only multi-band capable peer should be reported
128289284Srpaulo	 * Returns: Address of the next connected STA, %NULL if no more STAs
129289284Srpaulo	 *          connected
130289284Srpaulo	 */
131289284Srpaulo	const u8 * (*get_peer_next)(void *ctx,
132289284Srpaulo				    struct fst_get_peer_ctx **get_ctx,
133289284Srpaulo				    Boolean mb_only);
134289284Srpaulo};
135289284Srpaulo
136289284Srpaulo/**
137289284Srpaulo * fst_global_init - Global FST module initiator
138289284Srpaulo * Returns: 0 for success, negative error code for failure.
139289284Srpaulo * Note: The purpose of this function is to allocate and initiate global
140289284Srpaulo *       FST module data structures (linked lists, static data etc.)
141289284Srpaulo *       This function should be called prior to the 1st %fst_attach call.
142289284Srpaulo */
143289284Srpauloint fst_global_init(void);
144289284Srpaulo
145289284Srpaulo/**
146289284Srpaulo * fst_global_deinit - Global FST module de-initiator
147289284Srpaulo * Note: The purpose of this function is to deallocate and de-initiate global
148289284Srpaulo *       FST module data structures (linked lists, static data etc.)
149289284Srpaulo */
150289284Srpaulovoid fst_global_deinit(void);
151289284Srpaulo
152289284Srpaulo/**
153289284Srpaulo * struct fst_ctrl - Notification interface for FST module
154289284Srpaulo */
155289284Srpaulostruct fst_ctrl {
156289284Srpaulo	/**
157289284Srpaulo	 * init - Initialize the notification interface
158289284Srpaulo	 * Returns: 0 for success, negative error code for failure.
159289284Srpaulo	 */
160289284Srpaulo	int (*init)(void);
161289284Srpaulo
162289284Srpaulo	/**
163289284Srpaulo	 * deinit - Deinitialize the notification interface
164289284Srpaulo	 */
165289284Srpaulo	void (*deinit)(void);
166289284Srpaulo
167289284Srpaulo	/**
168289284Srpaulo	 * on_group_created - Notify about FST group creation
169289284Srpaulo	 * Returns: 0 for success, negative error code for failure.
170289284Srpaulo	 */
171289284Srpaulo	int (*on_group_created)(struct fst_group *g);
172289284Srpaulo
173289284Srpaulo	/**
174289284Srpaulo	 * on_group_deleted - Notify about FST group deletion
175289284Srpaulo	 */
176289284Srpaulo	void (*on_group_deleted)(struct fst_group *g);
177289284Srpaulo
178289284Srpaulo	/**
179289284Srpaulo	 * on_iface_added - Notify about interface addition
180289284Srpaulo	 * Returns: 0 for success, negative error code for failure.
181289284Srpaulo	 */
182289284Srpaulo	int (*on_iface_added)(struct fst_iface *i);
183289284Srpaulo
184289284Srpaulo	/**
185289284Srpaulo	 * on_iface_removed - Notify about interface removal
186289284Srpaulo	 */
187289284Srpaulo	void (*on_iface_removed)(struct fst_iface *i);
188289284Srpaulo
189289284Srpaulo	/**
190289284Srpaulo	 * on_session_added - Notify about FST session addition
191289284Srpaulo	 * Returns: 0 for success, negative error code for failure.
192289284Srpaulo	 */
193289284Srpaulo	int (*on_session_added)(struct fst_session *s);
194289284Srpaulo
195289284Srpaulo	/**
196289284Srpaulo	 * on_session_removed - Notify about FST session removal
197289284Srpaulo	 */
198289284Srpaulo	void (*on_session_removed)(struct fst_session *s);
199289284Srpaulo
200289284Srpaulo	/**
201289284Srpaulo	 * on_event - Notify about FST event
202289284Srpaulo	 * @event_type: Event type
203289284Srpaulo	 * @i: Interface object that relates to the event or NULL
204289284Srpaulo	 * @g: Group object that relates to the event or NULL
205289284Srpaulo	 * @extra - Event specific data (see fst_ctrl_iface.h for more info)
206289284Srpaulo	 */
207289284Srpaulo	void (*on_event)(enum fst_event_type event_type, struct fst_iface *i,
208289284Srpaulo			 struct fst_session *s,
209289284Srpaulo			 const union fst_event_extra *extra);
210289284Srpaulo};
211289284Srpaulo
212289284Srpaulostruct fst_ctrl_handle * fst_global_add_ctrl(const struct fst_ctrl *ctrl);
213289284Srpaulovoid fst_global_del_ctrl(struct fst_ctrl_handle *h);
214289284Srpaulo
215289284Srpaulo/**
216289284Srpaulo * NOTE: These values have to be read from configuration file
217289284Srpaulo */
218289284Srpaulostruct fst_iface_cfg {
219289284Srpaulo	char group_id[FST_MAX_GROUP_ID_LEN + 1];
220289284Srpaulo	u8 priority;
221289284Srpaulo	u32 llt;
222289284Srpaulo};
223289284Srpaulo
224289284Srpaulo/**
225289284Srpaulo * fst_attach - Attach interface to an FST group according to configuration read
226289284Srpaulo * @ifname: Interface name
227289284Srpaulo * @own_addr: Own interface MAC address
228289284Srpaulo * @iface_obj: Callbacks to be used by FST module to communicate with
229289284Srpaulo *             hostapd/wpa_supplicant
230289284Srpaulo * @cfg: FST-related interface configuration read from the configuration file
231289284Srpaulo * Returns: FST interface object for success, %NULL for failure.
232289284Srpaulo */
233289284Srpaulostruct fst_iface * fst_attach(const char *ifname,
234289284Srpaulo			      const u8 *own_addr,
235289284Srpaulo			      const struct fst_wpa_obj *iface_obj,
236289284Srpaulo			      const struct fst_iface_cfg *cfg);
237289284Srpaulo
238289284Srpaulo/**
239289284Srpaulo * fst_detach - Detach an interface
240289284Srpaulo * @iface: FST interface object
241289284Srpaulo */
242289284Srpaulovoid fst_detach(struct fst_iface *iface);
243289284Srpaulo
244289284Srpaulo/* FST module inputs */
245289284Srpaulo/**
246289284Srpaulo * fst_rx_action - FST Action frames handler
247289284Srpaulo * @iface: FST interface object
248289284Srpaulo * @mgmt: Action frame arrived
249289284Srpaulo * @len: Action frame length
250289284Srpaulo */
251289284Srpaulovoid fst_rx_action(struct fst_iface *iface, const struct ieee80211_mgmt *mgmt,
252289284Srpaulo		   size_t len);
253289284Srpaulo
254289284Srpaulo/**
255289284Srpaulo * fst_notify_peer_connected - FST STA connect handler
256289284Srpaulo * @iface: FST interface object
257289284Srpaulo * @addr: Address of the connected STA
258289284Srpaulo */
259289284Srpaulovoid fst_notify_peer_connected(struct fst_iface *iface, const u8 *addr);
260289284Srpaulo
261289284Srpaulo/**
262289284Srpaulo * fst_notify_peer_disconnected - FST STA disconnect handler
263289284Srpaulo * @iface: FST interface object
264289284Srpaulo * @addr: Address of the disconnected STA
265289284Srpaulo */
266289284Srpaulovoid fst_notify_peer_disconnected(struct fst_iface *iface, const u8 *addr);
267289284Srpaulo
268289284Srpaulo/* FST module auxiliary routines */
269289284Srpaulo
270289284Srpaulo/**
271289284Srpaulo * fst_are_ifaces_aggregated - Determines whether 2 interfaces belong to the
272289284Srpaulo *                             same FST group
273289284Srpaulo * @iface1: 1st FST interface object
274289284Srpaulo * @iface1: 2nd FST interface object
275289284Srpaulo *
276289284Srpaulo * Returns: %TRUE if the interfaces belong to the same FST group,
277289284Srpaulo *          %FALSE otherwise
278289284Srpaulo */
279289284SrpauloBoolean fst_are_ifaces_aggregated(struct fst_iface *iface1,
280289284Srpaulo				  struct fst_iface *iface2);
281289284Srpaulo
282289284Srpaulo#else /* CONFIG_FST */
283289284Srpaulo
284289284Srpaulostatic inline int fst_global_init(void)
285289284Srpaulo{
286289284Srpaulo	return 0;
287289284Srpaulo}
288289284Srpaulo
289289284Srpaulostatic inline int fst_global_start(void)
290289284Srpaulo{
291289284Srpaulo	return 0;
292289284Srpaulo}
293289284Srpaulo
294289284Srpaulostatic inline void fst_global_stop(void)
295289284Srpaulo{
296289284Srpaulo}
297289284Srpaulo
298289284Srpaulostatic inline void fst_global_deinit(void)
299289284Srpaulo{
300289284Srpaulo}
301289284Srpaulo
302289284Srpaulo#endif /* CONFIG_FST */
303289284Srpaulo
304289284Srpaulo#endif /* FST_H */
305