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 "gki.h"
33#include "pan_api.h"
34#include "bta_pan_api.h"
35#include "bta_pan_int.h"
36#include "bd.h"
37#include "utl.h"
38
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
88/* state table for listen state */
89const UINT8 bta_pan_st_idle[][BTA_PAN_NUM_COLS] =
90{
91   /* API_CLOSE */          {BTA_PAN_API_CLOSE,              BTA_PAN_IDLE_ST},
92   /* CI_TX_READY */        {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
93   /* CI_RX_READY */        {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
94   /* CI_TX_FLOW */         {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
95   /* CI_RX_WRITE */        {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
96   /* CI_RX_WRITEBUF */     {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
97   /* PAN_CONN_OPEN */      {BTA_PAN_CONN_OPEN,              BTA_PAN_OPEN_ST},
98   /* PAN_CONN_CLOSE */     {BTA_PAN_CONN_OPEN,              BTA_PAN_IDLE_ST},
99   /* FLOW_ENABLE */        {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST},
100   /* BNEP_DATA */          {BTA_PAN_IGNORE,                 BTA_PAN_IDLE_ST}
101
102};
103
104
105
106/* state table for open state */
107const UINT8 bta_pan_st_open[][BTA_PAN_NUM_COLS] =
108{
109   /* API_CLOSE */          {BTA_PAN_API_CLOSE,               BTA_PAN_OPEN_ST},
110   /* CI_TX_READY */        {BTA_PAN_TX_PATH,                 BTA_PAN_OPEN_ST},
111   /* CI_RX_READY */        {BTA_PAN_RX_PATH,                 BTA_PAN_OPEN_ST},
112   /* CI_TX_FLOW */         {BTA_PAN_TX_FLOW,                 BTA_PAN_OPEN_ST},
113   /* CI_RX_WRITE */        {BTA_PAN_IGNORE,                  BTA_PAN_OPEN_ST},
114   /* CI_RX_WRITEBUF */     {BTA_PAN_WRITE_BUF,               BTA_PAN_OPEN_ST},
115   /* PAN_CONN_OPEN */      {BTA_PAN_IGNORE,                  BTA_PAN_OPEN_ST},
116   /* PAN_CONN_CLOSE */     {BTA_PAN_CONN_CLOSE,              BTA_PAN_IDLE_ST},
117   /* FLOW_ENABLE */        {BTA_PAN_RX_PATH,                 BTA_PAN_OPEN_ST},
118   /* BNEP_DATA */          {BTA_PAN_TX_PATH,                 BTA_PAN_OPEN_ST}
119};
120
121/* state table for closing state */
122const UINT8 bta_pan_st_closing[][BTA_PAN_NUM_COLS] =
123{
124   /* API_CLOSE */          {BTA_PAN_IGNORE,                   BTA_PAN_CLOSING_ST},
125   /* CI_TX_READY */        {BTA_PAN_TX_PATH,                  BTA_PAN_CLOSING_ST},
126   /* CI_RX_READY */        {BTA_PAN_RX_PATH,                  BTA_PAN_CLOSING_ST},
127   /* CI_TX_FLOW */         {BTA_PAN_TX_FLOW,                  BTA_PAN_CLOSING_ST},
128   /* CI_RX_WRITE */        {BTA_PAN_IGNORE,                   BTA_PAN_CLOSING_ST},
129   /* CI_RX_WRITEBUF */     {BTA_PAN_FREE_BUF,                 BTA_PAN_CLOSING_ST},
130   /* PAN_CONN_OPEN */      {BTA_PAN_IGNORE,                   BTA_PAN_CLOSING_ST},
131   /* PAN_CONN_CLOSE */     {BTA_PAN_CONN_CLOSE,               BTA_PAN_IDLE_ST},
132   /* FLOW_ENABLE */        {BTA_PAN_RX_PATH,                  BTA_PAN_CLOSING_ST},
133   /* BNEP_DATA */          {BTA_PAN_TX_PATH,                  BTA_PAN_CLOSING_ST}
134};
135
136/* type for state table */
137typedef const UINT8 (*tBTA_PAN_ST_TBL)[BTA_PAN_NUM_COLS];
138
139/* state table */
140const tBTA_PAN_ST_TBL bta_pan_st_tbl[] = {
141    bta_pan_st_idle,
142    bta_pan_st_open,
143    bta_pan_st_closing
144};
145
146/*****************************************************************************
147** Global data
148*****************************************************************************/
149
150/* PAN control block */
151#if BTA_DYNAMIC_MEMORY == FALSE
152tBTA_PAN_CB  bta_pan_cb;
153#endif
154
155/*******************************************************************************
156**
157** Function         bta_pan_scb_alloc
158**
159** Description      Allocate a PAN server control block.
160**
161**
162** Returns          pointer to the scb, or NULL if none could be allocated.
163**
164*******************************************************************************/
165tBTA_PAN_SCB *bta_pan_scb_alloc(void)
166{
167    tBTA_PAN_SCB     *p_scb = &bta_pan_cb.scb[0];
168    int             i;
169
170    for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
171    {
172        if (!p_scb->in_use)
173        {
174            p_scb->in_use = TRUE;
175            APPL_TRACE_DEBUG("bta_pan_scb_alloc %d", i);
176            break;
177        }
178    }
179
180    if (i == BTA_PAN_NUM_CONN)
181    {
182        /* out of scbs */
183        p_scb = NULL;
184        APPL_TRACE_WARNING("Out of scbs");
185    }
186    return p_scb;
187}
188
189/*******************************************************************************
190**
191** Function         bta_pan_sm_execute
192**
193** Description      State machine event handling function for PAN
194**
195**
196** Returns          void
197**
198*******************************************************************************/
199static void bta_pan_sm_execute(tBTA_PAN_SCB *p_scb, UINT16 event, tBTA_PAN_DATA *p_data)
200{
201    tBTA_PAN_ST_TBL      state_table;
202    UINT8               action;
203    int                 i;
204
205    APPL_TRACE_EVENT("PAN scb=%d event=0x%x state=%d", bta_pan_scb_to_idx(p_scb), event, p_scb->state);
206
207    /* look up the state table for the current state */
208    state_table = bta_pan_st_tbl[p_scb->state];
209
210    event &= 0x00FF;
211
212    /* set next state */
213    p_scb->state = state_table[event][BTA_PAN_NEXT_STATE];
214
215    /* execute action functions */
216    for (i = 0; i < BTA_PAN_ACTIONS; i++)
217    {
218        if ((action = state_table[event][i]) != BTA_PAN_IGNORE)
219        {
220            (*bta_pan_action[action])(p_scb, p_data);
221        }
222        else
223        {
224            break;
225        }
226    }
227}
228
229/*******************************************************************************
230**
231** Function         bta_pan_api_enable
232**
233** Description      Handle an API enable event.
234**
235**
236** Returns          void
237**
238*******************************************************************************/
239static void bta_pan_api_enable(tBTA_PAN_DATA *p_data)
240{
241    /* initialize control block */
242    memset(&bta_pan_cb, 0, sizeof(bta_pan_cb));
243
244    /* store callback function */
245    bta_pan_cb.p_cback = p_data->api_enable.p_cback;
246    bta_pan_enable(p_data);
247}
248
249/*******************************************************************************
250**
251** Function         bta_pan_api_disable
252**
253** Description      Handle an API disable event.
254**
255**
256** Returns          void
257**
258*******************************************************************************/
259static void bta_pan_api_disable(tBTA_PAN_DATA *p_data)
260{
261    UNUSED(p_data);
262
263    bta_pan_disable();
264}
265
266
267/*******************************************************************************
268**
269** Function         bta_pan_api_open
270**
271** Description      Handle an API listen event.
272**
273**
274** Returns          void
275**
276*******************************************************************************/
277static void bta_pan_api_open(tBTA_PAN_DATA *p_data)
278{
279    tBTA_PAN_SCB     *p_scb;
280    tBTA_PAN_OPEN data;
281
282    /* allocate an scb */
283    if ((p_scb = bta_pan_scb_alloc()) != NULL)
284    {
285        bta_pan_open(p_scb, p_data);
286    }
287    else
288    {
289        bdcpy(data.bd_addr, p_data->api_open.bd_addr);
290        data.status = BTA_PAN_FAIL;
291        bta_pan_cb.p_cback(BTA_PAN_OPEN_EVT, (tBTA_PAN *)&data);
292
293    }
294}
295/*******************************************************************************
296**
297** Function         bta_pan_scb_dealloc
298**
299** Description      Deallocate a link control block.
300**
301**
302** Returns          void
303**
304*******************************************************************************/
305void bta_pan_scb_dealloc(tBTA_PAN_SCB *p_scb)
306{
307    APPL_TRACE_DEBUG("bta_pan_scb_dealloc %d", bta_pan_scb_to_idx(p_scb));
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*******************************************************************************/
321UINT8 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*******************************************************************************/
339tBTA_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*******************************************************************************/
368BOOLEAN 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