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 */
45 enum
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 */
61 typedef void (*tBTA_PAN_ACTION)(tBTA_PAN_SCB *p_scb, tBTA_PAN_DATA *p_data);
62 
63 
64 
65 
66 /* action function list */
67 const 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 */
88 const 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 */
106 const 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 */
121 const 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 */
136 typedef const UINT8 (*tBTA_PAN_ST_TBL)[BTA_PAN_NUM_COLS];
137 
138 /* state table */
139 const 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
151 tBTA_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 *******************************************************************************/
bta_pan_scb_alloc(void)164 tBTA_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 *******************************************************************************/
bta_pan_sm_execute(tBTA_PAN_SCB * p_scb,UINT16 event,tBTA_PAN_DATA * p_data)198 static 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 *******************************************************************************/
bta_pan_api_enable(tBTA_PAN_DATA * p_data)238 static 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 *******************************************************************************/
bta_pan_api_disable(tBTA_PAN_DATA * p_data)258 static 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 *******************************************************************************/
bta_pan_api_open(tBTA_PAN_DATA * p_data)276 static 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 *******************************************************************************/
bta_pan_scb_dealloc(tBTA_PAN_SCB * p_scb)304 void 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 *******************************************************************************/
bta_pan_scb_to_idx(tBTA_PAN_SCB * p_scb)320 UINT8 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 *******************************************************************************/
bta_pan_scb_by_handle(UINT16 handle)338 tBTA_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 *******************************************************************************/
bta_pan_hdl_event(BT_HDR * p_msg)367 BOOLEAN 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