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