1 /******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 * Copyright 2018-2019 NXP
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19 /******************************************************************************
20 *
21 * This is the main implementation file for the UWA system manager.
22 *
23 ******************************************************************************/
24 #include <string.h>
25
26 #include "uci_log.h"
27 #include "uwa_api.h"
28 #include "uwa_dm_int.h"
29 #include "uwa_sys.h"
30 #include "uwa_sys_int.h"
31 #include "uwb_osal_common.h"
32
33 /* protocol timer update period, in milliseconds */
34 #ifndef UWA_SYS_TIMER_PERIOD
35 #define UWA_SYS_TIMER_PERIOD 10
36 #endif
37
38 /* system manager control block definition */
39 tUWA_SYS_CB uwa_sys_cb =
40 {}; /* uwa_sys control block. statically initialize 'flags' field to 0 */
41
42 /*******************************************************************************
43 **
44 ** Function uwa_sys_init
45 **
46 ** Description UWA initialization; called from task initialization.
47 **
48 **
49 ** Returns void
50 **
51 *******************************************************************************/
uwa_sys_init(void)52 void uwa_sys_init(void) {
53 memset(&uwa_sys_cb, 0, sizeof(tUWA_SYS_CB));
54 uwa_sys_cb.flags |= UWA_SYS_FL_INITIALIZED;
55 uwa_sys_ptim_init(&uwa_sys_cb.ptim_cb, UWA_SYS_TIMER_PERIOD,
56 p_uwa_sys_cfg->timer);
57 }
58
59 /*******************************************************************************
60 **
61 ** Function uwa_sys_event
62 **
63 ** Description BTA event handler; called from task event handler.
64 **
65 **
66 ** Returns void
67 **
68 *******************************************************************************/
uwa_sys_event(UWB_HDR * p_msg)69 void uwa_sys_event(UWB_HDR* p_msg) {
70 uint8_t id;
71 bool freebuf = true;
72
73 UCI_TRACE_I("UWA got event 0x%04X", p_msg->event);
74
75 /* get subsystem id from event */
76 id = (uint8_t)(p_msg->event >> 8);
77
78 /* verify id and call subsystem event handler */
79 if ((id < UWA_ID_MAX) && (uwa_sys_cb.is_reg[id])) {
80 freebuf = (*uwa_sys_cb.reg[id]->evt_hdlr)(p_msg);
81 } else {
82 UCI_TRACE_W("UWA got unregistered event id %d", id);
83 }
84
85 if (freebuf) {
86 phUwb_GKI_freebuf(p_msg);
87 }
88 }
89
90 /*******************************************************************************
91 **
92 ** Function uwa_sys_timer_update
93 **
94 ** Description Update the BTA timer list and handle expired timers.
95 **
96 ** Returns void
97 **
98 *******************************************************************************/
uwa_sys_timer_update(void)99 void uwa_sys_timer_update(void) {
100 if (!uwa_sys_cb.timers_disabled) {
101 uwa_sys_ptim_timer_update(&uwa_sys_cb.ptim_cb);
102 }
103 }
104
105 /*******************************************************************************
106 **
107 ** Function uwa_sys_register
108 **
109 ** Description Called by other BTA subsystems to register their event
110 ** handler.
111 **
112 **
113 ** Returns void
114 **
115 *******************************************************************************/
uwa_sys_register(uint8_t id,const tUWA_SYS_REG * p_reg)116 void uwa_sys_register(uint8_t id, const tUWA_SYS_REG* p_reg) {
117 uwa_sys_cb.reg[id] = (tUWA_SYS_REG*)p_reg;
118 uwa_sys_cb.is_reg[id] = true;
119
120 if ((id != UWA_ID_DM) && (id != UWA_ID_SYS))
121 uwa_sys_cb.enable_cplt_mask |= (uint16_t)(0x0001 << id);
122
123 UCI_TRACE_I("id=%i, enable_cplt_mask=0x%x", id, uwa_sys_cb.enable_cplt_mask);
124 }
125
126 /*******************************************************************************
127 **
128 ** Function uwa_sys_check_disabled
129 **
130 ** Description If all subsystems above DM have been disabled, then
131 ** disable DM. Called during UWA shutdown
132 **
133 ** Returns void
134 **
135 *******************************************************************************/
uwa_sys_check_disabled(void)136 void uwa_sys_check_disabled(void) {
137 /* Disable DM */
138 if (uwa_sys_cb.is_reg[UWA_ID_DM]) {
139 (*uwa_sys_cb.reg[UWA_ID_DM]->disable)();
140 }
141 }
142
143 /*******************************************************************************
144 **
145 ** Function uwa_sys_deregister
146 **
147 ** Description Called by other BTA subsystems to de-register
148 ** handler.
149 **
150 **
151 ** Returns void
152 **
153 *******************************************************************************/
uwa_sys_deregister(uint8_t id)154 void uwa_sys_deregister(uint8_t id) {
155 UCI_TRACE_I("uwa_sys: deregistering subsystem %i", id);
156
157 uwa_sys_cb.is_reg[id] = false;
158
159 /* If not deregistering DM, then check if any other subsystems above DM are
160 * still */
161 /* registered. */
162 if (id != UWA_ID_DM) {
163 /* If all subsystems above UWA_DM have been disabled, then okay to disable
164 * DM */
165 uwa_sys_check_disabled();
166 } else {
167 /* DM (the final sub-system) is deregistering. Clear pending timer events in
168 * uwa_sys. */
169 uwa_sys_ptim_init(&uwa_sys_cb.ptim_cb, UWA_SYS_TIMER_PERIOD,
170 p_uwa_sys_cfg->timer);
171 }
172 }
173
174 /*******************************************************************************
175 **
176 ** Function uwa_sys_is_register
177 **
178 ** Description Called by other BTA subsystems to get registeration
179 ** status.
180 **
181 **
182 ** Returns void
183 **
184 *******************************************************************************/
uwa_sys_is_register(uint8_t id)185 bool uwa_sys_is_register(uint8_t id) { return uwa_sys_cb.is_reg[id]; }
186
187 /*******************************************************************************
188 **
189 ** Function uwa_sys_is_graceful_disable
190 **
191 ** Description Called by other BTA subsystems to get disable
192 ** parameter.
193 **
194 **
195 ** Returns void
196 **
197 *******************************************************************************/
uwa_sys_is_graceful_disable(void)198 bool uwa_sys_is_graceful_disable(void) { return uwa_sys_cb.graceful_disable; }
199
200 /*******************************************************************************
201 **
202 ** Function uwa_sys_enable_subsystems
203 **
204 ** Description Call on UWA Start up
205 **
206 ** Returns void
207 **
208 *******************************************************************************/
uwa_sys_enable_subsystems(void)209 void uwa_sys_enable_subsystems(void) {
210 uint8_t id;
211
212 UCI_TRACE_I("uwa_sys: enabling subsystems");
213
214 /* Enable all subsystems except SYS */
215 for (id = UWA_ID_DM; id < UWA_ID_MAX; id++) {
216 if (uwa_sys_cb.is_reg[id]) {
217 if (uwa_sys_cb.reg[id]->enable != NULL) {
218 /* Subsytem has a Disable fuuciton. Call it now */
219 (*uwa_sys_cb.reg[id]->enable)();
220 } else {
221 /* Subsytem does not have a Enable function. Report Enable on behalf of
222 * subsystem */
223 uwa_sys_cback_notify_enable_complete(id);
224 }
225 }
226 }
227 }
228
229 /*******************************************************************************
230 **
231 ** Function uwa_sys_disable_subsystems
232 **
233 ** Description Call on UWA shutdown. Disable all subsystems above UWA_DM
234 **
235 ** Returns void
236 **
237 *******************************************************************************/
uwa_sys_disable_subsystems(bool graceful)238 void uwa_sys_disable_subsystems(bool graceful) {
239 UCI_TRACE_I("uwa_sys: disabling subsystems:%d", graceful);
240 uwa_sys_cb.graceful_disable = graceful;
241
242 /* Disable DM */
243 if (uwa_sys_cb.is_reg[UWA_ID_DM]) {
244 (*uwa_sys_cb.reg[UWA_ID_DM]->disable)();
245 }
246 }
247
248 /*******************************************************************************
249 **
250 ** Function uwa_sys_sendmsg
251 **
252 ** Description Send a GKI message to BTA. This function is designed to
253 ** optimize sending of messages to BTA. It is called by BTA
254 ** API functions and call-in functions.
255 **
256 **
257 ** Returns void
258 **
259 *******************************************************************************/
uwa_sys_sendmsg(void * p_msg)260 void uwa_sys_sendmsg(void* p_msg) {
261 phUwb_GKI_send_msg(UWB_TASK, p_uwa_sys_cfg->mbox, p_msg);
262 }
263
264 /*******************************************************************************
265 **
266 ** Function uwa_sys_start_timer
267 **
268 ** Description Start a protocol timer for the specified amount
269 ** of time in milliseconds.
270 **
271 ** Returns void
272 **
273 *******************************************************************************/
uwa_sys_start_timer(TIMER_LIST_ENT * p_tle,uint16_t type,uint32_t timeout)274 void uwa_sys_start_timer(TIMER_LIST_ENT* p_tle, uint16_t type,
275 uint32_t timeout) {
276 uwa_sys_ptim_start_timer(&uwa_sys_cb.ptim_cb, p_tle, type, timeout);
277 }
278
279 /*******************************************************************************
280 **
281 ** Function uwa_sys_stop_timer
282 **
283 ** Description Stop a BTA timer.
284 **
285 ** Returns void
286 **
287 *******************************************************************************/
uwa_sys_stop_timer(TIMER_LIST_ENT * p_tle)288 void uwa_sys_stop_timer(TIMER_LIST_ENT* p_tle) {
289 uwa_sys_ptim_stop_timer(&uwa_sys_cb.ptim_cb, p_tle);
290 }
291
292 /*******************************************************************************
293 **
294 ** Function uwa_sys_disable_timers
295 **
296 ** Description Disable sys timer event handling
297 **
298 ** Returns void
299 **
300 *******************************************************************************/
uwa_sys_disable_timers(void)301 void uwa_sys_disable_timers(void) { uwa_sys_cb.timers_disabled = true; }
302