blob: 7fa05085f3c5380603b6be4127e1123962324612 [file] [log] [blame]
The Android Open Source Project5738f832012-12-12 16:00:35 -08001/******************************************************************************
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 "gki.h"
33#include "pan_api.h"
34#include "bta_pan_api.h"
35#include "bta_pan_int.h"
36#include "bd.h"
Mike J. Chen5cd8bff2014-01-31 18:16:59 -080037#include "utl.h"
The Android Open Source Project5738f832012-12-12 16:00:35 -080038
39/*****************************************************************************
40** Constants and types
41*****************************************************************************/
42
43
44
45/* state machine action enumeration list */
46enum
47{
48 BTA_PAN_API_CLOSE,
49 BTA_PAN_TX_PATH,
50 BTA_PAN_RX_PATH,
51 BTA_PAN_TX_FLOW,
52 BTA_PAN_WRITE_BUF,
53 BTA_PAN_CONN_OPEN,
54 BTA_PAN_CONN_CLOSE,
55 BTA_PAN_FREE_BUF,
56 BTA_PAN_IGNORE
57};
58
59
60
61/* type for action functions */
62typedef void (*tBTA_PAN_ACTION)(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data);
63
64
65
66
67/* action function list */
68const tBTA_PAN_ACTION bta_pan_action[] =
69{
70 bta_pan_api_close,
71 bta_pan_tx_path,
72 bta_pan_rx_path,
73 bta_pan_tx_flow,
74 bta_pan_write_buf,
75 bta_pan_conn_open,
76 bta_pan_conn_close,
77 bta_pan_free_buf,
78
79};
80
81/* state table information */
82#define BTA_PAN_ACTIONS 1 /* number of actions */
83#define BTA_PAN_NEXT_STATE 1 /* position of next state */
84#define BTA_PAN_NUM_COLS 2 /* number of columns in state tables */
85
86
87/* state machine states */
88enum
89{
90 BTA_PAN_IDLE_ST,
91 BTA_PAN_OPEN_ST,
92 BTA_PAN_CLOSING_ST
93};
94
95
96/* state table for listen state */
97const UINT8 bta_pan_st_idle[][BTA_PAN_NUM_COLS] =
98{
99 /* API_CLOSE */ {BTA_PAN_API_CLOSE, BTA_PAN_IDLE_ST},
100 /* CI_TX_READY */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
101 /* CI_RX_READY */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
102 /* CI_TX_FLOW */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
103 /* CI_RX_WRITE */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
104 /* CI_RX_WRITEBUF */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
105 /* PAN_CONN_OPEN */ {BTA_PAN_CONN_OPEN, BTA_PAN_OPEN_ST},
106 /* PAN_CONN_CLOSE */ {BTA_PAN_CONN_OPEN, BTA_PAN_IDLE_ST},
107 /* FLOW_ENABLE */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST},
108 /* BNEP_DATA */ {BTA_PAN_IGNORE, BTA_PAN_IDLE_ST}
109
110};
111
112
113
114/* state table for open state */
115const UINT8 bta_pan_st_open[][BTA_PAN_NUM_COLS] =
116{
117 /* API_CLOSE */ {BTA_PAN_API_CLOSE, BTA_PAN_OPEN_ST},
118 /* CI_TX_READY */ {BTA_PAN_TX_PATH, BTA_PAN_OPEN_ST},
119 /* CI_RX_READY */ {BTA_PAN_RX_PATH, BTA_PAN_OPEN_ST},
120 /* CI_TX_FLOW */ {BTA_PAN_TX_FLOW, BTA_PAN_OPEN_ST},
121 /* CI_RX_WRITE */ {BTA_PAN_IGNORE, BTA_PAN_OPEN_ST},
122 /* CI_RX_WRITEBUF */ {BTA_PAN_WRITE_BUF, BTA_PAN_OPEN_ST},
123 /* PAN_CONN_OPEN */ {BTA_PAN_IGNORE, BTA_PAN_OPEN_ST},
124 /* PAN_CONN_CLOSE */ {BTA_PAN_CONN_CLOSE, BTA_PAN_IDLE_ST},
125 /* FLOW_ENABLE */ {BTA_PAN_RX_PATH, BTA_PAN_OPEN_ST},
126 /* BNEP_DATA */ {BTA_PAN_TX_PATH, BTA_PAN_OPEN_ST}
127};
128
129/* state table for closing state */
130const UINT8 bta_pan_st_closing[][BTA_PAN_NUM_COLS] =
131{
132 /* API_CLOSE */ {BTA_PAN_IGNORE, BTA_PAN_CLOSING_ST},
133 /* CI_TX_READY */ {BTA_PAN_TX_PATH, BTA_PAN_CLOSING_ST},
134 /* CI_RX_READY */ {BTA_PAN_RX_PATH, BTA_PAN_CLOSING_ST},
135 /* CI_TX_FLOW */ {BTA_PAN_TX_FLOW, BTA_PAN_CLOSING_ST},
136 /* CI_RX_WRITE */ {BTA_PAN_IGNORE, BTA_PAN_CLOSING_ST},
137 /* CI_RX_WRITEBUF */ {BTA_PAN_FREE_BUF, BTA_PAN_CLOSING_ST},
138 /* PAN_CONN_OPEN */ {BTA_PAN_IGNORE, BTA_PAN_CLOSING_ST},
139 /* PAN_CONN_CLOSE */ {BTA_PAN_CONN_CLOSE, BTA_PAN_IDLE_ST},
140 /* FLOW_ENABLE */ {BTA_PAN_RX_PATH, BTA_PAN_CLOSING_ST},
141 /* BNEP_DATA */ {BTA_PAN_TX_PATH, BTA_PAN_CLOSING_ST}
142};
143
144/* type for state table */
145typedef const UINT8 (*tBTA_PAN_ST_TBL)[BTA_PAN_NUM_COLS];
146
147/* state table */
148const tBTA_PAN_ST_TBL bta_pan_st_tbl[] = {
149 bta_pan_st_idle,
150 bta_pan_st_open,
151 bta_pan_st_closing
152};
153
154/*****************************************************************************
155** Global data
156*****************************************************************************/
157
158/* PAN control block */
159#if BTA_DYNAMIC_MEMORY == FALSE
160tBTA_PAN_CB bta_pan_cb;
161#endif
162
163/*******************************************************************************
164**
165** Function bta_pan_scb_alloc
166**
167** Description Allocate a PAN server control block.
168**
169**
170** Returns pointer to the scb, or NULL if none could be allocated.
171**
172*******************************************************************************/
173tBTA_PAN_SCB *bta_pan_scb_alloc(void)
174{
175 tBTA_PAN_SCB *p_scb = &bta_pan_cb.scb[0];
176 int i;
177
178 for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
179 {
180 if (!p_scb->in_use)
181 {
182 p_scb->in_use = TRUE;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700183 APPL_TRACE_DEBUG("bta_pan_scb_alloc %d", i);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800184 break;
185 }
186 }
187
188 if (i == BTA_PAN_NUM_CONN)
189 {
190 /* out of scbs */
191 p_scb = NULL;
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700192 APPL_TRACE_WARNING("Out of scbs");
The Android Open Source Project5738f832012-12-12 16:00:35 -0800193 }
194 return p_scb;
195}
196
197/*******************************************************************************
198**
199** Function bta_pan_sm_execute
200**
201** Description State machine event handling function for PAN
202**
203**
204** Returns void
205**
206*******************************************************************************/
207static void bta_pan_sm_execute(tBTA_PAN_SCB *p_scb, UINT16 event, tBTA_PAN_DATA *p_data)
208{
209 tBTA_PAN_ST_TBL state_table;
210 UINT8 action;
211 int i;
212
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700213 APPL_TRACE_EVENT("PAN scb=%d event=0x%x state=%d", bta_pan_scb_to_idx(p_scb), event, p_scb->state);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800214
215 /* look up the state table for the current state */
216 state_table = bta_pan_st_tbl[p_scb->state];
217
218 event &= 0x00FF;
219
220 /* set next state */
221 p_scb->state = state_table[event][BTA_PAN_NEXT_STATE];
222
223 /* execute action functions */
224 for (i = 0; i < BTA_PAN_ACTIONS; i++)
225 {
226 if ((action = state_table[event][i]) != BTA_PAN_IGNORE)
227 {
228 (*bta_pan_action[action])(p_scb, p_data);
229 }
230 else
231 {
232 break;
233 }
234 }
235}
236
237/*******************************************************************************
238**
239** Function bta_pan_api_enable
240**
241** Description Handle an API enable event.
242**
243**
244** Returns void
245**
246*******************************************************************************/
247static void bta_pan_api_enable(tBTA_PAN_DATA *p_data)
248{
249 /* initialize control block */
250 memset(&bta_pan_cb, 0, sizeof(bta_pan_cb));
251
252 /* store callback function */
253 bta_pan_cb.p_cback = p_data->api_enable.p_cback;
254 bta_pan_enable(p_data);
255}
256
257/*******************************************************************************
258**
259** Function bta_pan_api_disable
260**
261** Description Handle an API disable event.
262**
263**
264** Returns void
265**
266*******************************************************************************/
267static void bta_pan_api_disable(tBTA_PAN_DATA *p_data)
268{
Mike J. Chen5cd8bff2014-01-31 18:16:59 -0800269 UNUSED(p_data);
270
The Android Open Source Project5738f832012-12-12 16:00:35 -0800271 bta_pan_disable();
272}
273
274
275/*******************************************************************************
276**
277** Function bta_pan_api_open
278**
279** Description Handle an API listen event.
280**
281**
282** Returns void
283**
284*******************************************************************************/
285static void bta_pan_api_open(tBTA_PAN_DATA *p_data)
286{
287 tBTA_PAN_SCB *p_scb;
288 tBTA_PAN_OPEN data;
289
290 /* allocate an scb */
291 if ((p_scb = bta_pan_scb_alloc()) != NULL)
292 {
293 bta_pan_open(p_scb, p_data);
294 }
295 else
296 {
297 bdcpy(data.bd_addr, p_data->api_open.bd_addr);
298 data.status = BTA_PAN_FAIL;
299 bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, (tBTA_PAN *)&data);
300
301 }
302}
303/*******************************************************************************
304**
305** Function bta_pan_scb_dealloc
306**
307** Description Deallocate a link control block.
308**
309**
310** Returns void
311**
312*******************************************************************************/
313void bta_pan_scb_dealloc(tBTA_PAN_SCB *p_scb)
314{
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700315 APPL_TRACE_DEBUG("bta_pan_scb_dealloc %d", bta_pan_scb_to_idx(p_scb));
The Android Open Source Project5738f832012-12-12 16:00:35 -0800316 memset(p_scb, 0, sizeof(tBTA_PAN_SCB));
317}
318
319/*******************************************************************************
320**
321** Function bta_pan_scb_to_idx
322**
323** Description Given a pointer to an scb, return its index.
324**
325**
326** Returns Index of scb.
327**
328*******************************************************************************/
329UINT8 bta_pan_scb_to_idx(tBTA_PAN_SCB *p_scb)
330{
331
332 return ((UINT8) (p_scb - bta_pan_cb.scb)) + 1;
333}
334
335
336
337/*******************************************************************************
338**
339** Function bta_pan_scb_by_handle
340**
341** Description Find scb associated with handle.
342**
343**
344** Returns Pointer to scb or NULL if not found.
345**
346*******************************************************************************/
347tBTA_PAN_SCB *bta_pan_scb_by_handle(UINT16 handle)
348{
349 tBTA_PAN_SCB *p_scb = &bta_pan_cb.scb[0];
350 UINT8 i;
351
352 for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
353 {
354 if (p_scb->handle == handle)
355 {
356 return p_scb;;
357 }
358 }
359
360
Sharvil Nanavatie8c3d752014-05-04 10:12:26 -0700361 APPL_TRACE_WARNING("No scb for handle %d", handle);
The Android Open Source Project5738f832012-12-12 16:00:35 -0800362
363 return NULL;
364}
365
366/*******************************************************************************
367**
368** Function bta_pan_hdl_event
369**
370** Description Data gateway main event handling function.
371**
372**
373** Returns void
374**
375*******************************************************************************/
376BOOLEAN bta_pan_hdl_event(BT_HDR *p_msg)
377{
378 tBTA_PAN_SCB *p_scb;
379 BOOLEAN freebuf = TRUE;
380
381 switch (p_msg->event)
382 {
383 /* handle enable event */
384 case BTA_PAN_API_ENABLE_EVT:
385 bta_pan_api_enable((tBTA_PAN_DATA *) p_msg);
386 break;
387
388 /* handle disable event */
389 case BTA_PAN_API_DISABLE_EVT:
390 bta_pan_api_disable((tBTA_PAN_DATA *) p_msg);
391 break;
392
393 /* handle set role event */
394 case BTA_PAN_API_SET_ROLE_EVT:
395 bta_pan_set_role((tBTA_PAN_DATA *) p_msg);
396 break;
397
398 /* handle open event */
399 case BTA_PAN_API_OPEN_EVT:
400 bta_pan_api_open((tBTA_PAN_DATA *) p_msg);
401 break;
402
403
404 /* events that require buffer not be released */
405 case BTA_PAN_CI_RX_WRITEBUF_EVT:
406 freebuf = FALSE;
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 /* all other events */
414 default:
415 if ((p_scb = bta_pan_scb_by_handle(p_msg->layer_specific)) != NULL)
416 {
417 bta_pan_sm_execute(p_scb, p_msg->event, (tBTA_PAN_DATA *) p_msg);
418 }
419 break;
420
421 }
422 return freebuf;
423}
424#endif /* BTA_PAN_INCLUDED */