1 /******************************************************************************
3 * Copyright (C) 2004-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains the PAN main functions and state machine.
23 ******************************************************************************/
25 #include "bt_target.h"
27 #if defined(BTA_PAN_INCLUDED) && (BTA_PAN_INCLUDED == TRUE)
32 #include "bt_common.h"
34 #include "bta_pan_api.h"
35 #include "bta_pan_int.h"
38 /*****************************************************************************
39 ** Constants and types
40 *****************************************************************************/
44 /* state machine action enumeration list */
60 /* type for action functions */
61 typedef void (*tBTA_PAN_ACTION)(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data);
66 /* action function list */
67 const tBTA_PAN_ACTION bta_pan_action[] =
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 */
87 /* state table for listen state */
88 const UINT8 bta_pan_st_idle[][BTA_PAN_NUM_COLS] =
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}
105 /* state table for open state */
106 const UINT8 bta_pan_st_open[][BTA_PAN_NUM_COLS] =
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}
120 /* state table for closing state */
121 const UINT8 bta_pan_st_closing[][BTA_PAN_NUM_COLS] =
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}
135 /* type for state table */
136 typedef const UINT8 (*tBTA_PAN_ST_TBL)[BTA_PAN_NUM_COLS];
139 const tBTA_PAN_ST_TBL bta_pan_st_tbl[] = {
145 /*****************************************************************************
147 *****************************************************************************/
149 /* PAN control block */
150 #if BTA_DYNAMIC_MEMORY == FALSE
151 tBTA_PAN_CB bta_pan_cb;
154 /*******************************************************************************
156 ** Function bta_pan_scb_alloc
158 ** Description Allocate a PAN server control block.
161 ** Returns pointer to the scb, or NULL if none could be allocated.
163 *******************************************************************************/
164 tBTA_PAN_SCB *bta_pan_scb_alloc(void)
166 tBTA_PAN_SCB *p_scb = &bta_pan_cb.scb[0];
169 for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
173 p_scb->in_use = TRUE;
174 APPL_TRACE_DEBUG("bta_pan_scb_alloc %d", i);
179 if (i == BTA_PAN_NUM_CONN)
183 APPL_TRACE_WARNING("Out of scbs");
188 /*******************************************************************************
190 ** Function bta_pan_sm_execute
192 ** Description State machine event handling function for PAN
197 *******************************************************************************/
198 static void bta_pan_sm_execute(tBTA_PAN_SCB *p_scb, UINT16 event, tBTA_PAN_DATA *p_data)
200 tBTA_PAN_ST_TBL state_table;
204 APPL_TRACE_EVENT("PAN scb=%d event=0x%x state=%d", bta_pan_scb_to_idx(p_scb), event, p_scb->state);
206 /* look up the state table for the current state */
207 state_table = bta_pan_st_tbl[p_scb->state];
212 p_scb->state = state_table[event][BTA_PAN_NEXT_STATE];
214 /* execute action functions */
215 for (i = 0; i < BTA_PAN_ACTIONS; i++)
217 if ((action = state_table[event][i]) != BTA_PAN_IGNORE)
219 (*bta_pan_action[action])(p_scb, p_data);
228 /*******************************************************************************
230 ** Function bta_pan_api_enable
232 ** Description Handle an API enable event.
237 *******************************************************************************/
238 static void bta_pan_api_enable(tBTA_PAN_DATA *p_data)
240 /* initialize control block */
241 memset(&bta_pan_cb, 0, sizeof(bta_pan_cb));
243 /* store callback function */
244 bta_pan_cb.p_cback = p_data->api_enable.p_cback;
245 bta_pan_enable(p_data);
248 /*******************************************************************************
250 ** Function bta_pan_api_disable
252 ** Description Handle an API disable event.
257 *******************************************************************************/
258 static void bta_pan_api_disable(tBTA_PAN_DATA *p_data)
266 /*******************************************************************************
268 ** Function bta_pan_api_open
270 ** Description Handle an API listen event.
275 *******************************************************************************/
276 static void bta_pan_api_open(tBTA_PAN_DATA *p_data)
281 /* allocate an scb */
282 if ((p_scb = bta_pan_scb_alloc()) != NULL)
284 bta_pan_open(p_scb, p_data);
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);
294 /*******************************************************************************
296 ** Function bta_pan_scb_dealloc
298 ** Description Deallocate a link control block.
303 *******************************************************************************/
304 void bta_pan_scb_dealloc(tBTA_PAN_SCB *p_scb)
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));
311 /*******************************************************************************
313 ** Function bta_pan_scb_to_idx
315 ** Description Given a pointer to an scb, return its index.
318 ** Returns Index of scb.
320 *******************************************************************************/
321 UINT8 bta_pan_scb_to_idx(tBTA_PAN_SCB *p_scb)
324 return ((UINT8) (p_scb - bta_pan_cb.scb)) + 1;
329 /*******************************************************************************
331 ** Function bta_pan_scb_by_handle
333 ** Description Find scb associated with handle.
336 ** Returns Pointer to scb or NULL if not found.
338 *******************************************************************************/
339 tBTA_PAN_SCB *bta_pan_scb_by_handle(UINT16 handle)
341 tBTA_PAN_SCB *p_scb = &bta_pan_cb.scb[0];
344 for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
346 if (p_scb->handle == handle)
353 APPL_TRACE_WARNING("No scb for handle %d", handle);
358 /*******************************************************************************
360 ** Function bta_pan_hdl_event
362 ** Description Data gateway main event handling function.
367 *******************************************************************************/
368 BOOLEAN bta_pan_hdl_event(BT_HDR *p_msg)
371 BOOLEAN freebuf = TRUE;
373 switch (p_msg->event)
375 /* handle enable event */
376 case BTA_PAN_API_ENABLE_EVT:
377 bta_pan_api_enable((tBTA_PAN_DATA *) p_msg);
380 /* handle disable event */
381 case BTA_PAN_API_DISABLE_EVT:
382 bta_pan_api_disable((tBTA_PAN_DATA *) p_msg);
385 /* handle set role event */
386 case BTA_PAN_API_SET_ROLE_EVT:
387 bta_pan_set_role((tBTA_PAN_DATA *) p_msg);
390 /* handle open event */
391 case BTA_PAN_API_OPEN_EVT:
392 bta_pan_api_open((tBTA_PAN_DATA *) p_msg);
396 /* events that require buffer not be released */
397 case BTA_PAN_CI_RX_WRITEBUF_EVT:
399 if ((p_scb = bta_pan_scb_by_handle(p_msg->layer_specific)) != NULL)
401 bta_pan_sm_execute(p_scb, p_msg->event, (tBTA_PAN_DATA *) p_msg);
405 /* all other events */
407 if ((p_scb = bta_pan_scb_by_handle(p_msg->layer_specific)) != NULL)
409 bta_pan_sm_execute(p_scb, p_msg->event, (tBTA_PAN_DATA *) p_msg);
416 #endif /* BTA_PAN_INCLUDED */