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 "utl.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
87/* state table for listen state */
88const 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 */
106const 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 */
121const 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 */
136typedef const UINT8 (*tBTA_PAN_ST_TBL)[BTA_PAN_NUM_COLS];
137
138/* state table */
139const 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
151tBTA_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*******************************************************************************/
164tBTA_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*******************************************************************************/
198static 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*******************************************************************************/
238static 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*******************************************************************************/
258static 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*******************************************************************************/
276static 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*******************************************************************************/
304void 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    memset(p_scb, 0, sizeof(tBTA_PAN_SCB));
308}
309
310/*******************************************************************************
311**
312** Function         bta_pan_scb_to_idx
313**
314** Description      Given a pointer to an scb, return its index.
315**
316**
317** Returns          Index of scb.
318**
319*******************************************************************************/
320UINT8 bta_pan_scb_to_idx(tBTA_PAN_SCB *p_scb)
321{
322
323    return ((UINT8) (p_scb - bta_pan_cb.scb)) + 1;
324}
325
326
327
328/*******************************************************************************
329**
330** Function         bta_pan_scb_by_handle
331**
332** Description      Find scb associated with handle.
333**
334**
335** Returns          Pointer to scb or NULL if not found.
336**
337*******************************************************************************/
338tBTA_PAN_SCB *bta_pan_scb_by_handle(UINT16 handle)
339{
340    tBTA_PAN_SCB     *p_scb = &bta_pan_cb.scb[0];
341    UINT8 i;
342
343    for (i = 0; i < BTA_PAN_NUM_CONN; i++, p_scb++)
344    {
345        if (p_scb->handle == handle)
346        {
347            return p_scb;;
348        }
349    }
350
351
352    APPL_TRACE_WARNING("No scb for handle %d", handle);
353
354    return NULL;
355}
356
357/*******************************************************************************
358**
359** Function         bta_pan_hdl_event
360**
361** Description      Data gateway main event handling function.
362**
363**
364** Returns          void
365**
366*******************************************************************************/
367BOOLEAN bta_pan_hdl_event(BT_HDR *p_msg)
368{
369    tBTA_PAN_SCB *p_scb;
370    BOOLEAN     freebuf = TRUE;
371
372    switch (p_msg->event)
373    {
374        /* handle enable event */
375        case BTA_PAN_API_ENABLE_EVT:
376            bta_pan_api_enable((tBTA_PAN_DATA *) p_msg);
377            break;
378
379        /* handle disable event */
380        case BTA_PAN_API_DISABLE_EVT:
381            bta_pan_api_disable((tBTA_PAN_DATA *) p_msg);
382            break;
383
384        /* handle set role event */
385        case BTA_PAN_API_SET_ROLE_EVT:
386            bta_pan_set_role((tBTA_PAN_DATA *) p_msg);
387            break;
388
389        /* handle open event */
390        case BTA_PAN_API_OPEN_EVT:
391            bta_pan_api_open((tBTA_PAN_DATA *) p_msg);
392            break;
393
394
395        /* events that require buffer not be released */
396        case BTA_PAN_CI_RX_WRITEBUF_EVT:
397            freebuf = FALSE;
398            if ((p_scb = bta_pan_scb_by_handle(p_msg->layer_specific)) != NULL)
399            {
400                bta_pan_sm_execute(p_scb, p_msg->event, (tBTA_PAN_DATA *) p_msg);
401            }
402            break;
403
404        /* all other events */
405        default:
406            if ((p_scb = bta_pan_scb_by_handle(p_msg->layer_specific)) != NULL)
407            {
408                bta_pan_sm_execute(p_scb, p_msg->event, (tBTA_PAN_DATA *) p_msg);
409            }
410            break;
411
412    }
413    return freebuf;
414}
415#endif /* BTA_PAN_INCLUDED */
416