1 /******************************************************************************
2 *
3 * Copyright (C) 2004-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file contains the PAN main functions and state machine.
22 *
23 ******************************************************************************/
24
25 #include "bt_target.h"
26
27 #if defined(BTA_PAN_INCLUDED) && (BTA_PAN_INCLUDED == TRUE)
28
29 #include <string.h>
30 #include "bta_api.h"
31 #include "bta_sys.h"
32 #include "bt_common.h"
33 #include "pan_api.h"
34 #include "bta_pan_api.h"
35 #include "bta_pan_int.h"
36 #include "utl.h"
37
38 /*****************************************************************************
39 ** Constants and types
40 *****************************************************************************/
41
42
43
44 /* state machine action enumeration list */
45 enum
46 {
47 BTA_PAN_API_CLOSE,
48 BTA_PAN_TX_PATH,
49 BTA_PAN_RX_PATH,
50 BTA_PAN_TX_FLOW,
51 BTA_PAN_WRITE_BUF,
52 BTA_PAN_CONN_OPEN,
53 BTA_PAN_CONN_CLOSE,
54 BTA_PAN_FREE_BUF,
55 BTA_PAN_IGNORE
56 };
57
58
59
60 /* type for action functions */
61 typedef void (*tBTA_PAN_ACTION)(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data);
62
63
64
65
66 /* action function list */
67 const tBTA_PAN_ACTION bta_pan_action[] =
68 {
69 bta_pan_api_close,
70 bta_pan_tx_path,
71 bta_pan_rx_path,
72 bta_pan_tx_flow,
73 bta_pan_write_buf,
74 bta_pan_conn_open,
75 bta_pan_conn_close,
76 bta_pan_free_buf,
77
78 };
79
80 /* state table information */
81 #define BTA_PAN_ACTIONS 1 /* number of actions */
82 #define BTA_PAN_NEXT_STATE 1 /* position of next state */
83 #define BTA_PAN_NUM_COLS 2 /* number of columns in state tables */
84
85
86
87 /* state table for listen state */
88 const UINT8 bta_pan_st_idle[][BTA_PAN_NUM_COLS] =
89 {
90 /* API_CLOSE */ {BTA_PAN_API_CLOSE, BTA_PAN_IDLE_ST},
91 /* CI_TX_READY */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
92 /* CI_RX_READY */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
93 /* CI_TX_FLOW */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
94 /* CI_RX_WRITE */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
95 /* CI_RX_WRITEBUF */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
96 /* PAN_CONN_OPEN */ {BTA_PAN_CONN_OPEN, BTA_PAN_OPEN_ST},
97 /* PAN_CONN_CLOSE */ {BTA_PAN_CONN_OPEN, BTA_PAN_IDLE_ST},
98 /* FLOW_ENABLE */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
99 /* BNEP_DATA */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST}
100
101 };
102
103
104
105 /* state table for open state */
106 const UINT8 bta_pan_st_open[][BTA_PAN_NUM_COLS] =
107 {
108 /* API_CLOSE */ {BTA_PAN_API_CLOSE, BTA_PAN_OPEN_ST},
109 /* CI_TX_READY */ {BTA_PAN_TX_PATH, BTA_PAN_OPEN_ST},
110 /* CI_RX_READY */ {BTA_PAN_RX_PATH, BTA_PAN_OPEN_ST},
111 /* CI_TX_FLOW */ {BTA_PAN_TX_FLOW, BTA_PAN_OPEN_ST},
112 /* CI_RX_WRITE */ {BTA_PAN_IGNORE, BTA_PAN_OPEN_ST},
113 /* CI_RX_WRITEBUF */ {BTA_PAN_WRITE_BUF, BTA_PAN_OPEN_ST},
114 /* PAN_CONN_OPEN */ {BTA_PAN_IGNORE, BTA_PAN_OPEN_ST},
115 /* PAN_CONN_CLOSE */ {BTA_PAN_CONN_CLOSE, BTA_PAN_IDLE_ST},
116 /* FLOW_ENABLE */ {BTA_PAN_RX_PATH, BTA_PAN_OPEN_ST},
117 /* BNEP_DATA */ {BTA_PAN_TX_PATH, BTA_PAN_OPEN_ST}
118 };
119
120 /* state table for closing state */
121 const UINT8 bta_pan_st_closing[][BTA_PAN_NUM_COLS] =
122 {
123 /* API_CLOSE */ {BTA_PAN_IGNORE, BTA_PAN_CLOSING_ST},
124 /* CI_TX_READY */ {BTA_PAN_TX_PATH, BTA_PAN_CLOSING_ST},
125 /* CI_RX_READY */ {BTA_PAN_RX_PATH, BTA_PAN_CLOSING_ST},
126 /* CI_TX_FLOW */ {BTA_PAN_TX_FLOW, BTA_PAN_CLOSING_ST},
127 /* CI_RX_WRITE */ {BTA_PAN_IGNORE, BTA_PAN_CLOSING_ST},
128 /* CI_RX_WRITEBUF */ {BTA_PAN_FREE_BUF, BTA_PAN_CLOSING_ST},
129 /* PAN_CONN_OPEN */ {BTA_PAN_IGNORE, BTA_PAN_CLOSING_ST},
130 /* PAN_CONN_CLOSE */ {BTA_PAN_CONN_CLOSE, BTA_PAN_IDLE_ST},
131 /* FLOW_ENABLE */ {BTA_PAN_RX_PATH, BTA_PAN_CLOSING_ST},
132 /* BNEP_DATA */ {BTA_PAN_TX_PATH, BTA_PAN_CLOSING_ST}
133 };
134
135 /* type for state table */
136 typedef const UINT8 (*tBTA_PAN_ST_TBL)[BTA_PAN_NUM_COLS];
137
138 /* state table */
139 const tBTA_PAN_ST_TBL bta_pan_st_tbl[] = {
140 bta_pan_st_idle,
141 bta_pan_st_open,
142 bta_pan_st_closing
143 };
144
145 /*****************************************************************************
146 ** Global data
147 *****************************************************************************/
148
149 /* PAN control block */
150 #if BTA_DYNAMIC_MEMORY == FALSE
151 tBTA_PAN_CB bta_pan_cb;
152 #endif
153
154 /*******************************************************************************
155 **
156 ** Function bta_pan_scb_alloc
157 **
158 ** Description Allocate a PAN server control block.
159 **
160 **
161 ** Returns pointer to the scb, or NULL if none could be allocated.
162 **
163 *******************************************************************************/
bta_pan_scb_alloc(void)164 tBTA_PAN_SCB *bta_pan_scb_alloc(void)
165 {
166 tBTA_PAN_SCB *p_scb = &bta_pan_cb.scb[0];
167 int i;
168
169 for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
170 {
171 if (!p_scb->in_use)
172 {
173 p_scb->in_use = TRUE;
174 APPL_TRACE_DEBUG("bta_pan_scb_alloc %d", i);
175 break;
176 }
177 }
178
179 if (i == BTA_PAN_NUM_CONN)
180 {
181 /* out of scbs */
182 p_scb = NULL;
183 APPL_TRACE_WARNING("Out of scbs");
184 }
185 return p_scb;
186 }
187
188 /*******************************************************************************
189 **
190 ** Function bta_pan_sm_execute
191 **
192 ** Description State machine event handling function for PAN
193 **
194 **
195 ** Returns void
196 **
197 *******************************************************************************/
bta_pan_sm_execute(tBTA_PAN_SCB * p_scb,UINT16 event,tBTA_PAN_DATA * p_data)198 static void bta_pan_sm_execute(tBTA_PAN_SCB *p_scb, UINT16 event, tBTA_PAN_DATA *p_data)
199 {
200 tBTA_PAN_ST_TBL state_table;
201 UINT8 action;
202 int i;
203
204 APPL_TRACE_EVENT("PAN scb=%d event=0x%x state=%d", bta_pan_scb_to_idx(p_scb), event, p_scb->state);
205
206 /* look up the state table for the current state */
207 state_table = bta_pan_st_tbl[p_scb->state];
208
209 event &= 0x00FF;
210
211 /* set next state */
212 p_scb->state = state_table[event][BTA_PAN_NEXT_STATE];
213
214 /* execute action functions */
215 for (i = 0; i < BTA_PAN_ACTIONS; i++)
216 {
217 if ((action = state_table[event][i]) != BTA_PAN_IGNORE)
218 {
219 (*bta_pan_action[action])(p_scb, p_data);
220 }
221 else
222 {
223 break;
224 }
225 }
226 }
227
228 /*******************************************************************************
229 **
230 ** Function bta_pan_api_enable
231 **
232 ** Description Handle an API enable event.
233 **
234 **
235 ** Returns void
236 **
237 *******************************************************************************/
bta_pan_api_enable(tBTA_PAN_DATA * p_data)238 static void bta_pan_api_enable(tBTA_PAN_DATA *p_data)
239 {
240 /* initialize control block */
241 memset(&bta_pan_cb, 0, sizeof(bta_pan_cb));
242
243 /* store callback function */
244 bta_pan_cb.p_cback = p_data->api_enable.p_cback;
245 bta_pan_enable(p_data);
246 }
247
248 /*******************************************************************************
249 **
250 ** Function bta_pan_api_disable
251 **
252 ** Description Handle an API disable event.
253 **
254 **
255 ** Returns void
256 **
257 *******************************************************************************/
bta_pan_api_disable(tBTA_PAN_DATA * p_data)258 static void bta_pan_api_disable(tBTA_PAN_DATA *p_data)
259 {
260 UNUSED(p_data);
261
262 bta_pan_disable();
263 }
264
265
266 /*******************************************************************************
267 **
268 ** Function bta_pan_api_open
269 **
270 ** Description Handle an API listen event.
271 **
272 **
273 ** Returns void
274 **
275 *******************************************************************************/
bta_pan_api_open(tBTA_PAN_DATA * p_data)276 static void bta_pan_api_open(tBTA_PAN_DATA *p_data)
277 {
278 tBTA_PAN_SCB *p_scb;
279 tBTA_PAN_OPEN data;
280
281 /* allocate an scb */
282 if ((p_scb = bta_pan_scb_alloc()) != NULL)
283 {
284 bta_pan_open(p_scb, p_data);
285 }
286 else
287 {
288 bdcpy(data.bd_addr, p_data->api_open.bd_addr);
289 data.status = BTA_PAN_FAIL;
290 bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, (tBTA_PAN *)&data);
291
292 }
293 }
294 /*******************************************************************************
295 **
296 ** Function bta_pan_scb_dealloc
297 **
298 ** Description Deallocate a link control block.
299 **
300 **
301 ** Returns void
302 **
303 *******************************************************************************/
bta_pan_scb_dealloc(tBTA_PAN_SCB * p_scb)304 void bta_pan_scb_dealloc(tBTA_PAN_SCB *p_scb)
305 {
306 APPL_TRACE_DEBUG("bta_pan_scb_dealloc %d", bta_pan_scb_to_idx(p_scb));
307 fixed_queue_free(p_scb->data_queue, NULL);
308 memset(p_scb, 0, sizeof(tBTA_PAN_SCB));
309 }
310
311 /*******************************************************************************
312 **
313 ** Function bta_pan_scb_to_idx
314 **
315 ** Description Given a pointer to an scb, return its index.
316 **
317 **
318 ** Returns Index of scb.
319 **
320 *******************************************************************************/
bta_pan_scb_to_idx(tBTA_PAN_SCB * p_scb)321 UINT8 bta_pan_scb_to_idx(tBTA_PAN_SCB *p_scb)
322 {
323
324 return ((UINT8) (p_scb - bta_pan_cb.scb)) + 1;
325 }
326
327
328
329 /*******************************************************************************
330 **
331 ** Function bta_pan_scb_by_handle
332 **
333 ** Description Find scb associated with handle.
334 **
335 **
336 ** Returns Pointer to scb or NULL if not found.
337 **
338 *******************************************************************************/
bta_pan_scb_by_handle(UINT16 handle)339 tBTA_PAN_SCB *bta_pan_scb_by_handle(UINT16 handle)
340 {
341 tBTA_PAN_SCB *p_scb = &bta_pan_cb.scb[0];
342 UINT8 i;
343
344 for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
345 {
346 if (p_scb->handle == handle)
347 {
348 return p_scb;;
349 }
350 }
351
352
353 APPL_TRACE_WARNING("No scb for handle %d", handle);
354
355 return NULL;
356 }
357
358 /*******************************************************************************
359 **
360 ** Function bta_pan_hdl_event
361 **
362 ** Description Data gateway main event handling function.
363 **
364 **
365 ** Returns void
366 **
367 *******************************************************************************/
bta_pan_hdl_event(BT_HDR * p_msg)368 BOOLEAN bta_pan_hdl_event(BT_HDR *p_msg)
369 {
370 tBTA_PAN_SCB *p_scb;
371 BOOLEAN freebuf = TRUE;
372
373 switch (p_msg->event)
374 {
375 /* handle enable event */
376 case BTA_PAN_API_ENABLE_EVT:
377 bta_pan_api_enable((tBTA_PAN_DATA *) p_msg);
378 break;
379
380 /* handle disable event */
381 case BTA_PAN_API_DISABLE_EVT:
382 bta_pan_api_disable((tBTA_PAN_DATA *) p_msg);
383 break;
384
385 /* handle set role event */
386 case BTA_PAN_API_SET_ROLE_EVT:
387 bta_pan_set_role((tBTA_PAN_DATA *) p_msg);
388 break;
389
390 /* handle open event */
391 case BTA_PAN_API_OPEN_EVT:
392 bta_pan_api_open((tBTA_PAN_DATA *) p_msg);
393 break;
394
395
396 /* events that require buffer not be released */
397 case BTA_PAN_CI_RX_WRITEBUF_EVT:
398 freebuf = FALSE;
399 if ((p_scb = bta_pan_scb_by_handle(p_msg->layer_specific)) != NULL)
400 {
401 bta_pan_sm_execute(p_scb, p_msg->event, (tBTA_PAN_DATA *) p_msg);
402 }
403 break;
404
405 /* all other events */
406 default:
407 if ((p_scb = bta_pan_scb_by_handle(p_msg->layer_specific)) != NULL)
408 {
409 bta_pan_sm_execute(p_scb, p_msg->event, (tBTA_PAN_DATA *) p_msg);
410 }
411 break;
412
413 }
414 return freebuf;
415 }
416 #endif /* BTA_PAN_INCLUDED */
417