• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
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 /* state machine states */
87 enum
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 */
96 const 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 */
114 const 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 */
129 const 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 */
144 typedef const UINT8 (*tBTA_PAN_ST_TBL)[BTA_PAN_NUM_COLS];
145 
146 /* state table */
147 const 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
159 tBTA_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 *******************************************************************************/
bta_pan_scb_alloc(void)172 tBTA_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 *******************************************************************************/
bta_pan_sm_execute(tBTA_PAN_SCB * p_scb,UINT16 event,tBTA_PAN_DATA * p_data)206 static 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 *******************************************************************************/
bta_pan_api_enable(tBTA_PAN_DATA * p_data)246 static 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 *******************************************************************************/
bta_pan_api_disable(tBTA_PAN_DATA * p_data)266 static 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 *******************************************************************************/
bta_pan_api_open(tBTA_PAN_DATA * p_data)282 static 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 *******************************************************************************/
bta_pan_scb_dealloc(tBTA_PAN_SCB * p_scb)310 void 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 *******************************************************************************/
bta_pan_scb_to_idx(tBTA_PAN_SCB * p_scb)326 UINT8 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 *******************************************************************************/
bta_pan_scb_by_handle(UINT16 handle)344 tBTA_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 *******************************************************************************/
bta_pan_hdl_event(BT_HDR * p_msg)373 BOOLEAN 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 */
422