nfa_sys_main.c revision e29968cf3e053557a9c2efc5a7a42d0767c51d9d
1/*****************************************************************************
2**
3**  Name:           nfa_sys_main.c
4**
5**  Description:    This is the main implementation file for the NFA
6**                  system manager.
7**
8**  Copyright (c) 2010, Broadcom Corp., All Rights Reserved.
9**  Broadcom Bluetooth Core. Proprietary and confidential.
10**
11*****************************************************************************/
12#include <string.h>
13#include "nfa_api.h"
14#include "nfa_sys.h"
15#include "nfa_sys_int.h"
16#include "nfa_sys_ptim.h"
17#include "nfa_dm_int.h"
18
19/* protocol timer update period, in milliseconds */
20#ifndef NFA_SYS_TIMER_PERIOD
21#define NFA_SYS_TIMER_PERIOD            10
22#endif
23
24/* system manager control block definition */
25#if NFA_DYNAMIC_MEMORY == FALSE
26tNFA_SYS_CB nfa_sys_cb = {0};   /* nfa_sys control block. statically initialize 'flags' field to 0 */
27#endif
28
29/*******************************************************************************
30**
31** Function         nfa_sys_init
32**
33** Description      NFA initialization; called from task initialization.
34**
35**
36** Returns          void
37**
38*******************************************************************************/
39void nfa_sys_init (void)
40{
41    memset (&nfa_sys_cb, 0, sizeof (tNFA_SYS_CB));
42    nfa_sys_cb.flags |= NFA_SYS_FL_INITIALIZED;
43    nfa_sys_ptim_init (&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD, p_nfa_sys_cfg->timer);
44    nfa_sys_cb.trace_level = p_nfa_sys_cfg->trace_level;
45}
46
47
48
49
50/*******************************************************************************
51**
52** Function         nfa_sys_event
53**
54** Description      BTA event handler; called from task event handler.
55**
56**
57** Returns          void
58**
59*******************************************************************************/
60void nfa_sys_event (BT_HDR *p_msg)
61{
62    UINT8       id;
63    BOOLEAN     freebuf = TRUE;
64
65    NFA_TRACE_EVENT1 ("NFA got event 0x%04X", p_msg->event);
66
67    /* get subsystem id from event */
68    id = (UINT8) (p_msg->event >> 8);
69
70    /* verify id and call subsystem event handler */
71    if ((id < NFA_ID_MAX) && (nfa_sys_cb.is_reg[id]))
72    {
73        freebuf = (*nfa_sys_cb.reg[id]->evt_hdlr) (p_msg);
74    }
75    else
76    {
77        NFA_TRACE_WARNING1 ("NFA got unregistered event id %d", id);
78    }
79
80    if (freebuf)
81    {
82        GKI_freebuf (p_msg);
83    }
84}
85
86/*******************************************************************************
87**
88** Function         nfa_sys_timer_update
89**
90** Description      Update the BTA timer list and handle expired timers.
91**
92** Returns          void
93**
94*******************************************************************************/
95void nfa_sys_timer_update (void)
96{
97    if (!nfa_sys_cb.timers_disabled)
98    {
99        nfa_sys_ptim_timer_update (&nfa_sys_cb.ptim_cb);
100    }
101}
102
103/*******************************************************************************
104**
105** Function         nfa_sys_register
106**
107** Description      Called by other BTA subsystems to register their event
108**                  handler.
109**
110**
111** Returns          void
112**
113*******************************************************************************/
114void nfa_sys_register (UINT8 id, const tNFA_SYS_REG *p_reg)
115{
116    nfa_sys_cb.reg[id] = (tNFA_SYS_REG *) p_reg;
117    nfa_sys_cb.is_reg[id] = TRUE;
118
119    if ((id != NFA_ID_DM) && (id != NFA_ID_SYS))
120        nfa_sys_cb.enable_cplt_mask |= (0x0001 << id);
121
122    if (id != NFA_ID_SYS)
123    {
124        if (p_reg->proc_nfcc_pwr_mode)
125            nfa_sys_cb.proc_nfcc_pwr_mode_cplt_mask |= (0x0001 << id);
126    }
127
128    NFA_TRACE_DEBUG2 ("nfa_sys_register () id=%i, enable_cplt_mask=0x%x",
129                       id, nfa_sys_cb.enable_cplt_mask);
130}
131
132
133/*******************************************************************************
134**
135** Function         nfa_sys_check_disabled
136**
137** Description      If all subsystems above DM have been disabled, then
138**                  disable DM. Called during NFA shutdown
139**
140** Returns          void
141**
142*******************************************************************************/
143void nfa_sys_check_disabled (void)
144{
145    UINT8 id;
146    UINT8 done = TRUE;
147
148    /* Check if all subsystems above DM have been disabled. */
149    for (id = (NFA_ID_DM+1); id < NFA_ID_MAX; id++)
150    {
151        if (nfa_sys_cb.is_reg[id])
152        {
153            /* as long as one subsystem is not done */
154            done = FALSE;
155            break;
156        }
157    }
158
159    /* All subsystems disabled. disable DM */
160    if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM]))
161    {
162        (*nfa_sys_cb.reg[NFA_ID_DM]->disable) ();
163    }
164}
165
166
167/*******************************************************************************
168**
169** Function         nfa_sys_deregister
170**
171** Description      Called by other BTA subsystems to de-register
172**                  handler.
173**
174**
175** Returns          void
176**
177*******************************************************************************/
178void nfa_sys_deregister (UINT8 id)
179{
180    NFA_TRACE_DEBUG1 ("nfa_sys: deregistering subsystem %i", id);
181
182    nfa_sys_cb.is_reg[id] = FALSE;
183
184    /* If not deregistering DM, then check if any other subsystems above DM are still  */
185    /* registered.                                                                  */
186    if (id != NFA_ID_DM)
187    {
188        /* If all subsystems above NFA_DM have been disabled, then okay to disable DM */
189        nfa_sys_check_disabled ();
190    }
191    else
192    {
193        /* DM (the final sub-system) is deregistering. Clear pending timer events in nfa_sys. */
194        nfa_sys_ptim_init (&nfa_sys_cb.ptim_cb, NFA_SYS_TIMER_PERIOD, p_nfa_sys_cfg->timer);
195    }
196}
197
198/*******************************************************************************
199**
200** Function         nfa_sys_is_register
201**
202** Description      Called by other BTA subsystems to get registeration
203**                  status.
204**
205**
206** Returns          void
207**
208*******************************************************************************/
209BOOLEAN nfa_sys_is_register (UINT8 id)
210{
211    return nfa_sys_cb.is_reg[id];
212}
213
214/*******************************************************************************
215**
216** Function         nfa_sys_is_graceful_disable
217**
218** Description      Called by other BTA subsystems to get disable
219**                  parameter.
220**
221**
222** Returns          void
223**
224*******************************************************************************/
225BOOLEAN nfa_sys_is_graceful_disable (void)
226{
227    return nfa_sys_cb.graceful_disable;
228}
229
230/*******************************************************************************
231**
232** Function         nfa_sys_enable_subsystems
233**
234** Description      Call on NFA Start up
235**
236** Returns          void
237**
238*******************************************************************************/
239void nfa_sys_enable_subsystems (void)
240{
241    UINT8 id;
242
243    NFA_TRACE_DEBUG0 ("nfa_sys: enabling subsystems");
244
245    /* Disable all subsystems above NFA_DM. (NFA_DM and NFA_SYS will be disabled last) */
246    for (id = NFA_ID_VS_PRE; id < NFA_ID_MAX; id++)
247    {
248        if (nfa_sys_cb.is_reg[id])
249        {
250            if (nfa_sys_cb.reg[id]->enable != NULL)
251            {
252                /* Subsytem has a Disable funciton. Call it now */
253                (*nfa_sys_cb.reg[id]->enable) ();
254            }
255            else
256            {
257                /* Subsytem does not have a Enable function. Report Enable on behalf of subsystem */
258                nfa_sys_cback_notify_enable_complete (id);
259            }
260        }
261    }
262}
263
264/*******************************************************************************
265**
266** Function         nfa_sys_disable_subsystems
267**
268** Description      Call on NFA shutdown. Disable all subsystems above NFA_DM
269**
270** Returns          void
271**
272*******************************************************************************/
273void nfa_sys_disable_subsystems (BOOLEAN graceful)
274{
275    UINT8 id;
276    BOOLEAN done = TRUE;
277
278    NFA_TRACE_DEBUG1 ("nfa_sys: disabling subsystems:%d", graceful);
279    nfa_sys_cb.graceful_disable = graceful;
280
281    /* Disable all subsystems above NFA_DM. (NFA_DM and NFA_SYS will be disabled last) */
282    for (id = (NFA_ID_DM+1); id < NFA_ID_MAX; id++)
283    {
284        if (nfa_sys_cb.is_reg[id])
285        {
286            done = FALSE;
287            if (nfa_sys_cb.reg[id]->disable != NULL)
288            {
289                /* Subsytem has a Disable funciton. Call it now */
290                (*nfa_sys_cb.reg[id]->disable) ();
291            }
292            else
293            {
294                /* Subsytem does not have a Disable function. Deregister on behalf of subsystem */
295                nfa_sys_deregister (id);
296            }
297        }
298    }
299
300    /* If All subsystems disabled. disable DM */
301    if ((done) && (nfa_sys_cb.is_reg[NFA_ID_DM]))
302    {
303        (*nfa_sys_cb.reg[NFA_ID_DM]->disable) ();
304    }
305}
306
307/*******************************************************************************
308**
309** Function         nfa_sys_notify_nfcc_power_mode
310**
311** Description      Call to notify NFCC power mode to NFA sub-modules
312**
313** Returns          void
314**
315*******************************************************************************/
316void nfa_sys_notify_nfcc_power_mode (UINT8 nfcc_power_mode)
317{
318    UINT8 id;
319
320    NFA_TRACE_DEBUG1 ("nfa_sys: notify NFCC power mode(%d) to subsystems", nfcc_power_mode);
321
322    /* Notify NFCC power state to all subsystems except NFA_SYS */
323    for (id = NFA_ID_VS_PRE; id < NFA_ID_MAX; id++)
324    {
325        if ((nfa_sys_cb.is_reg[id]) && (nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode))
326        {
327            /* Subsytem has a funciton for processing NFCC power mode. Call it now */
328            (*nfa_sys_cb.reg[id]->proc_nfcc_pwr_mode) (nfcc_power_mode);
329        }
330    }
331}
332
333/*******************************************************************************
334**
335** Function         nfa_sys_sendmsg
336**
337** Description      Send a GKI message to BTA.  This function is designed to
338**                  optimize sending of messages to BTA.  It is called by BTA
339**                  API functions and call-in functions.
340**
341**
342** Returns          void
343**
344*******************************************************************************/
345void nfa_sys_sendmsg (void *p_msg)
346{
347    GKI_send_msg (NFC_TASK, p_nfa_sys_cfg->mbox, p_msg);
348}
349
350/*******************************************************************************
351**
352** Function         nfa_sys_start_timer
353**
354** Description      Start a protocol timer for the specified amount
355**                  of time in milliseconds.
356**
357** Returns          void
358**
359*******************************************************************************/
360void nfa_sys_start_timer (TIMER_LIST_ENT *p_tle, UINT16 type, INT32 timeout)
361{
362    nfa_sys_ptim_start_timer (&nfa_sys_cb.ptim_cb, p_tle, type, timeout);
363}
364
365/*******************************************************************************
366**
367** Function         nfa_sys_stop_timer
368**
369** Description      Stop a BTA timer.
370**
371** Returns          void
372**
373*******************************************************************************/
374void nfa_sys_stop_timer (TIMER_LIST_ENT *p_tle)
375{
376    nfa_sys_ptim_stop_timer (&nfa_sys_cb.ptim_cb, p_tle);
377}
378
379
380/*******************************************************************************
381**
382** Function         nfa_sys_disable_timers
383**
384** Description      Disable sys timer event handling
385**
386** Returns          void
387**
388*******************************************************************************/
389void nfa_sys_disable_timers (void)
390{
391    nfa_sys_cb.timers_disabled = TRUE;
392}
393
394/*******************************************************************************
395**
396** Function         nfa_sys_set_trace_level
397**
398** Description      Set trace level for BTA
399**
400** Returns          void
401**
402*******************************************************************************/
403void nfa_sys_set_trace_level (UINT8 level)
404{
405    nfa_sys_cb.trace_level = level;
406}
407