blob: 9c86a098bb7dae38c1e5202a6a3d0f9af75064fd [file] [log] [blame]
Jeff Johnson295189b2012-06-20 16:38:30 -07001/*
Jeff Johnson32d95a32012-09-10 13:15:23 -07002 * Copyright (c) 2012, The Linux Foundation. All rights reserved.
Jeff Johnson295189b2012-06-20 16:38:30 -07003 *
4 * Previously licensed under the ISC license by Qualcomm Atheros, Inc.
5 *
6 *
7 * Permission to use, copy, modify, and/or distribute this software for
8 * any purpose with or without fee is hereby granted, provided that the
9 * above copyright notice and this permission notice appear in all
10 * copies.
11 *
12 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL
13 * WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED
14 * WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE
15 * AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
16 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
17 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
18 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
19 * PERFORMANCE OF THIS SOFTWARE.
20 */
21
22/******************************************************************************
23*
24* Name: btcApi.c
25*
26* Description: Routines that make up the BTC API.
27*
28* Copyright 2008 (c) Qualcomm, Incorporated. All Rights Reserved.
29* Qualcomm Confidential and Proprietary.
30*
31******************************************************************************/
32#include "wlan_qct_wda.h"
33#ifndef WLAN_MDM_CODE_REDUCTION_OPT
34#include "aniGlobal.h"
35#include "smsDebug.h"
36#include "btcApi.h"
37#include "cfgApi.h"
38#include "pmc.h"
39#include "smeQosInternal.h"
40#ifdef FEATURE_WLAN_DIAG_SUPPORT
41#include "vos_diag_core_event.h"
42#include "vos_diag_core_log.h"
43#endif /* FEATURE_WLAN_DIAG_SUPPORT */
44static void btcLogEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent);
45static void btcRestoreHeartBeatMonitoringHandle(void* hHal);
46static void btcUapsdCheck( tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent );
47VOS_STATUS btcCheckHeartBeatMonitoring(tHalHandle hHal, tpSmeBtEvent pBtEvent);
48static void btcPowerStateCB( v_PVOID_t pContext, tPmcState pmcState );
49static VOS_STATUS btcDeferEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent );
50static VOS_STATUS btcDeferDisconnEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent );
51#ifdef FEATURE_WLAN_DIAG_SUPPORT
52static void btcDiagEventLog (tHalHandle hHal, tpSmeBtEvent pBtEvent);
53#endif /* FEATURE_WLAN_DIAG_SUPPORT */
54/* ---------------------------------------------------------------------------
55 \fn btcOpen
56 \brief API to init the BTC Events Layer
57 \param hHal - The handle returned by macOpen.
58 \return VOS_STATUS
59 VOS_STATUS_E_FAILURE success
60 VOS_STATUS_SUCCESS failure
61 ---------------------------------------------------------------------------*/
62VOS_STATUS btcOpen (tHalHandle hHal)
63{
64 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
65 VOS_STATUS vosStatus;
66 /* Initialize BTC configuartion. */
67 pMac->btc.btcConfig.btcExecutionMode = BTC_SMART_COEXISTENCE;
68 pMac->btc.btcConfig.btcConsBtSlotsToBlockDuringDhcp = 0;
69 pMac->btc.btcConfig.btcA2DPBtSubIntervalsDuringDhcp = BTC_MAX_NUM_ACL_BT_SUB_INTS;
70 pMac->btc.btcConfig.btcBtIntervalMode1 = BTC_BT_INTERVAL_MODE1_DEFAULT;
71 pMac->btc.btcConfig.btcWlanIntervalMode1 = BTC_WLAN_INTERVAL_MODE1_DEFAULT;
72 pMac->btc.btcConfig.btcActionOnPmFail = BTC_START_NEXT;
Jeff Johnson32d95a32012-09-10 13:15:23 -070073
74 pMac->btc.btcConfig.btcStaticLenInqBt = BTC_STATIC_BT_LEN_INQ_DEF;
75 pMac->btc.btcConfig.btcStaticLenPageBt = BTC_STATIC_BT_LEN_PAGE_DEF;
76 pMac->btc.btcConfig.btcStaticLenConnBt = BTC_STATIC_BT_LEN_CONN_DEF;
77 pMac->btc.btcConfig.btcStaticLenLeBt = BTC_STATIC_BT_LEN_LE_DEF;
78 pMac->btc.btcConfig.btcStaticLenInqWlan = BTC_STATIC_WLAN_LEN_INQ_DEF;
79 pMac->btc.btcConfig.btcStaticLenPageWlan = BTC_STATIC_WLAN_LEN_PAGE_DEF;
80 pMac->btc.btcConfig.btcStaticLenConnWlan = BTC_STATIC_WLAN_LEN_CONN_DEF;
81 pMac->btc.btcConfig.btcStaticLenLeWlan = BTC_STATIC_WLAN_LEN_LE_DEF;
82 pMac->btc.btcConfig.btcDynMaxLenBt = BTC_DYNAMIC_BT_LEN_MAX_DEF;
83 pMac->btc.btcConfig.btcDynMaxLenWlan = BTC_DYNAMIC_WLAN_LEN_MAX_DEF;
84 pMac->btc.btcConfig.btcMaxScoBlockPerc = BTC_SCO_BLOCK_PERC_DEF;
85 pMac->btc.btcConfig.btcDhcpProtOnA2dp = BTC_DHCP_ON_A2DP_DEF;
86 pMac->btc.btcConfig.btcDhcpProtOnSco = BTC_DHCP_ON_SCO_DEF;
87
Jeff Johnson295189b2012-06-20 16:38:30 -070088 pMac->btc.btcReady = VOS_FALSE;
89 pMac->btc.btcEventState = 0;
90 pMac->btc.btcHBActive = VOS_TRUE;
91
92 vosStatus = vos_timer_init( &pMac->btc.restoreHBTimer,
93 VOS_TIMER_TYPE_SW,
94 btcRestoreHeartBeatMonitoringHandle,
95 (void*) hHal);
96 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
97 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcOpen: Fail to init timer");
98 return VOS_STATUS_E_FAILURE;
99 }
100 if( !HAL_STATUS_SUCCESS(pmcRegisterDeviceStateUpdateInd( pMac, btcPowerStateCB, pMac )) )
101 {
102 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcOpen: Fail to register PMC callback\n");
103 return VOS_STATUS_E_FAILURE;
104 }
105 return VOS_STATUS_SUCCESS;
106}
107/* ---------------------------------------------------------------------------
108 \fn btcClose
109 \brief API to exit the BTC Events Layer
110 \param hHal - The handle returned by macOpen.
111 \return VOS_STATUS
112 VOS_STATUS_E_FAILURE success
113 VOS_STATUS_SUCCESS failure
114 ---------------------------------------------------------------------------*/
115VOS_STATUS btcClose (tHalHandle hHal)
116{
117 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
118 VOS_STATUS vosStatus;
119 pMac->btc.btcReady = VOS_FALSE;
120 pMac->btc.btcUapsdOk = VOS_FALSE;
121 vos_timer_stop(&pMac->btc.restoreHBTimer);
122 vosStatus = vos_timer_destroy(&pMac->btc.restoreHBTimer);
123 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
124 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcClose: Fail to destroy timer");
125 return VOS_STATUS_E_FAILURE;
126 }
127 if(!HAL_STATUS_SUCCESS(
128 pmcDeregisterDeviceStateUpdateInd(pMac, btcPowerStateCB)))
129 {
130 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
131 "%s: %d: cannot deregister with pmcDeregisterDeviceStateUpdateInd()",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700132 __func__, __LINE__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700133 }
134
135 return VOS_STATUS_SUCCESS;
136}
137
138/* ---------------------------------------------------------------------------
139 \fn btcReady
140 \brief fn to inform BTC that eWNI_SME_SYS_READY_IND has been sent to PE.
141 This acts as a trigger to send a message to HAL to update the BTC
142 related conig to FW. Note that if HDD configures any power BTC
143 related stuff before this API is invoked, BTC will buffer all the
144 configutaion.
145 \param hHal - The handle returned by macOpen.
146 \return VOS_STATUS
147 ---------------------------------------------------------------------------*/
148VOS_STATUS btcReady (tHalHandle hHal)
149{
150 tpAniSirGlobal pMac = PMAC_STRUCT(hHal);
151 v_U32_t cfgVal = 0;
152 v_U8_t i;
153 pMac->btc.btcReady = VOS_TRUE;
154 pMac->btc.btcUapsdOk = VOS_TRUE;
155 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
156 {
157 pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE;
158 }
159
160 // Read heartbeat threshold CFG and save it.
161 ccmCfgGetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, &cfgVal);
162 pMac->btc.btcHBCount = (v_U8_t)cfgVal;
163 if (btcSendCfgMsg(hHal, &(pMac->btc.btcConfig)) != VOS_STATUS_SUCCESS)
164 {
165 return VOS_STATUS_E_FAILURE;
166 }
167 return VOS_STATUS_SUCCESS;
168}
169
170static VOS_STATUS btcSendBTEvent(tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent)
171{
172 vos_msg_t msg;
173 tpSmeBtEvent ptrSmeBtEvent = NULL;
174 switch(pBtEvent->btEventType)
175 {
176 case BT_EVENT_CREATE_SYNC_CONNECTION:
177 case BT_EVENT_SYNC_CONNECTION_UPDATED:
178 if(pBtEvent->uEventParam.btSyncConnection.linkType != BT_SCO &&
179 pBtEvent->uEventParam.btSyncConnection.linkType != BT_eSCO)
180 {
181 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
182 "Invalid link type %d for Sync Connection. BT event will be dropped ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700183 __func__, pBtEvent->uEventParam.btSyncConnection.linkType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700184 return VOS_STATUS_E_FAILURE;
185 }
186 break;
187 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
188 if((pBtEvent->uEventParam.btSyncConnection.status == BT_CONN_STATUS_SUCCESS) &&
189 ((pBtEvent->uEventParam.btSyncConnection.linkType != BT_SCO && pBtEvent->uEventParam.btSyncConnection.linkType != BT_eSCO) ||
190 (pBtEvent->uEventParam.btSyncConnection.connectionHandle == BT_INVALID_CONN_HANDLE)))
191 {
192 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
193 "Invalid connection handle %d or link type %d for Sync Connection. BT event will be dropped ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700194 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700195 pBtEvent->uEventParam.btSyncConnection.connectionHandle,
196 pBtEvent->uEventParam.btSyncConnection.linkType);
197 return VOS_STATUS_E_FAILURE;
198 }
199 break;
200 case BT_EVENT_MODE_CHANGED:
201 if(pBtEvent->uEventParam.btAclModeChange.mode >= BT_ACL_MODE_MAX)
202 {
203 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
204 "Invalid mode %d for ACL Connection. BT event will be dropped ",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700205 __func__,
Jeff Johnson295189b2012-06-20 16:38:30 -0700206 pBtEvent->uEventParam.btAclModeChange.mode);
207 return VOS_STATUS_E_FAILURE;
208 }
209 break;
210 case BT_EVENT_DEVICE_SWITCHED_OFF:
211 pMac->btc.btcEventState = 0;
212 break;
213 default:
214 break;
215 }
216 ptrSmeBtEvent = vos_mem_malloc(sizeof(tSmeBtEvent));
217 if (NULL == ptrSmeBtEvent)
218 {
219 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700220 "Not able to allocate memory for BT event", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700221 return VOS_STATUS_E_FAILURE;
222 }
223 btcLogEvent(pMac, pBtEvent);
224#ifdef FEATURE_WLAN_DIAG_SUPPORT
225 btcDiagEventLog(pMac, pBtEvent);
226#endif
227 vos_mem_copy(ptrSmeBtEvent, pBtEvent, sizeof(tSmeBtEvent));
228 msg.type = WDA_SIGNAL_BT_EVENT;
229 msg.reserved = 0;
230 msg.bodyptr = ptrSmeBtEvent;
231 if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
232 {
233 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700234 "Not able to post WDA_SIGNAL_BT_EVENT message to WDA", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700235 vos_mem_free( ptrSmeBtEvent );
236 return VOS_STATUS_E_FAILURE;
237 }
238 // After successfully posting the message, check if heart beat
239 // monitoring needs to be turned off
240 (void)btcCheckHeartBeatMonitoring(pMac, pBtEvent);
241 //Check whether BTC and UAPSD can co-exist
242 btcUapsdCheck( pMac, pBtEvent );
243 return VOS_STATUS_SUCCESS;
244 }
245
246#ifndef WLAN_MDM_CODE_REDUCTION_OPT
247/* ---------------------------------------------------------------------------
248 \fn btcSignalBTEvent
249 \brief API to signal Bluetooth (BT) event to the WLAN driver. Based on the
250 BT event type and the current operating mode of Libra (full power,
251 BMPS, UAPSD etc), appropriate Bluetooth Coexistence (BTC) strategy
252 would be employed.
253 \param hHal - The handle returned by macOpen.
254 \param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent.
255 Caller owns the memory and is responsible for freeing it.
256 \return VOS_STATUS
257 VOS_STATUS_E_FAILURE – BT Event not passed to HAL. This can happen
258 if driver has not yet been initialized or if BTC
259 Events Layer has been disabled.
260 VOS_STATUS_SUCCESS – BT Event passed to HAL
261 ---------------------------------------------------------------------------*/
262VOS_STATUS btcSignalBTEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent)
263{
264 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
265 VOS_STATUS vosStatus;
266 if( NULL == pBtEvent )
267 {
268 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700269 "Null pointer for SME BT Event", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700270 return VOS_STATUS_E_FAILURE;
271 }
272 if(( BTC_WLAN_ONLY == pMac->btc.btcConfig.btcExecutionMode ) ||
273 ( BTC_PTA_ONLY == pMac->btc.btcConfig.btcExecutionMode ))
274 {
275 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700276 "BTC execution mode not set to BTC_SMART_COEXISTENCE. BT event will be dropped", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -0700277 return VOS_STATUS_E_FAILURE;
278 }
279 if( pBtEvent->btEventType < 0 || pBtEvent->btEventType >= BT_EVENT_TYPE_MAX )
280 {
281 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
282 "Invalid BT event %d being passed. BT event will be dropped",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -0700283 __func__, pBtEvent->btEventType);
Jeff Johnson295189b2012-06-20 16:38:30 -0700284 return VOS_STATUS_E_FAILURE;
285 }
286 //Check PMC state to make sure whether we need to defer
287 //If we already have deferred events, defer the new one as well, in case PMC is in transition state
288 if( pMac->btc.fReplayBTEvents || !PMC_IS_CHIP_ACCESSIBLE(pmcGetPmcState( pMac )) )
289 {
290 //We need to defer the event
291 vosStatus = btcDeferEvent(pMac, pBtEvent);
292 if( VOS_IS_STATUS_SUCCESS(vosStatus) )
293 {
294 pMac->btc.fReplayBTEvents = VOS_TRUE;
295 return VOS_STATUS_SUCCESS;
296 }
297 else
298 {
299 return vosStatus;
300 }
301 }
302 btcSendBTEvent(pMac, pBtEvent);
303 return VOS_STATUS_SUCCESS;
304}
305#endif
306/* ---------------------------------------------------------------------------
307 \fn btcCheckHeartBeatMonitoring
308 \brief API to check whether heartbeat monitoring is required to be disabled
309 for specific BT start events which takes significant time to complete
310 during which WLAN misses beacons. To avoid WLAN-MAC from disconnecting
311 for the not enough beacons received we stop the heartbeat timer during
312 this start BT event till the stop of that BT event.
313 \param hHal - The handle returned by macOpen.
314 \param pBtEvent - Pointer to a caller allocated object of type tSmeBtEvent.
315 Caller owns the memory and is responsible for freeing it.
316 \return VOS_STATUS
317 VOS_STATUS_E_FAILURE Config not passed to HAL.
318 VOS_STATUS_SUCCESS Config passed to HAL
319 ---------------------------------------------------------------------------*/
320VOS_STATUS btcCheckHeartBeatMonitoring(tHalHandle hHal, tpSmeBtEvent pBtEvent)
321{
322 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
323 VOS_STATUS vosStatus;
324 switch(pBtEvent->btEventType)
325 {
326 // Start events which requires heartbeat monitoring be disabled.
327 case BT_EVENT_INQUIRY_STARTED:
328 pMac->btc.btcEventState |= BT_INQUIRY_STARTED;
329 break;
330 case BT_EVENT_PAGE_STARTED:
331 pMac->btc.btcEventState |= BT_PAGE_STARTED;
332 break;
333 case BT_EVENT_CREATE_ACL_CONNECTION:
334 pMac->btc.btcEventState |= BT_CREATE_ACL_CONNECTION_STARTED;
335 break;
336 case BT_EVENT_CREATE_SYNC_CONNECTION:
337 pMac->btc.btcEventState |= BT_CREATE_SYNC_CONNECTION_STARTED;
338 break;
339 // Stop/done events which indicates heartbeat monitoring can be enabled
340 case BT_EVENT_INQUIRY_STOPPED:
341 pMac->btc.btcEventState &= ~(BT_INQUIRY_STARTED);
342 break;
343 case BT_EVENT_PAGE_STOPPED:
344 pMac->btc.btcEventState &= ~(BT_PAGE_STARTED);
345 break;
346 case BT_EVENT_ACL_CONNECTION_COMPLETE:
347 pMac->btc.btcEventState &= ~(BT_CREATE_ACL_CONNECTION_STARTED);
348 break;
349 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
350 pMac->btc.btcEventState &= ~(BT_CREATE_SYNC_CONNECTION_STARTED);
351 break;
352 default:
353 // Ignore other events
354 return VOS_STATUS_SUCCESS;
355 }
356 // Check if any of the BT start events are active
357 if (pMac->btc.btcEventState) {
358 if (pMac->btc.btcHBActive) {
359 // set heartbeat threshold CFG to zero
360 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0, NULL, eANI_BOOLEAN_FALSE);
361 pMac->btc.btcHBActive = VOS_FALSE;
362 }
363 // Deactivate and active the restore HB timer
364 vos_timer_stop( &pMac->btc.restoreHBTimer);
365 vosStatus= vos_timer_start( &pMac->btc.restoreHBTimer, BT_MAX_EVENT_DONE_TIMEOUT );
366 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
367 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcCheckHeartBeatMonitoring: Fail to start timer");
368 return VOS_STATUS_E_FAILURE;
369 }
370 } else {
371 // Restore CFG back to the original value only if it was disabled
372 if (!pMac->btc.btcHBActive) {
373 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE);
374 pMac->btc.btcHBActive = VOS_TRUE;
375 }
376 // Deactivate the timer
377 vosStatus = vos_timer_stop( &pMac->btc.restoreHBTimer);
378 if (!VOS_IS_STATUS_SUCCESS(vosStatus)) {
379 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcCheckHeartBeatMonitoring: Fail to stop timer");
380 return VOS_STATUS_E_FAILURE;
381 }
382 }
383 return VOS_STATUS_SUCCESS;
384}
385/* ---------------------------------------------------------------------------
386 \fn btcRestoreHeartBeatMonitoringHandle
387 \brief Timer handler to handlet the timeout condition when a specific BT
388 stop event does not come back, in which case to restore back the
389 heartbeat timer.
390 \param hHal - The handle returned by macOpen.
391 \return VOID
392 ---------------------------------------------------------------------------*/
393void btcRestoreHeartBeatMonitoringHandle(tHalHandle hHal)
394{
395 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
396 if( !pMac->btc.btcHBActive )
397 {
398 tPmcState pmcState;
399 //Check PMC state to make sure whether we need to defer
400 pmcState = pmcGetPmcState( pMac );
401 if( PMC_IS_CHIP_ACCESSIBLE(pmcState) )
402 {
403 // Restore CFG back to the original value
404 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE);
405 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BT event timeout, restoring back HeartBeat timer");
406 }
407 else
408 {
409 //defer it
410 pMac->btc.btcEventReplay.fRestoreHBMonitor = VOS_TRUE;
411 }
412 }
413}
414
415
416/* ---------------------------------------------------------------------------
417 \fn btcSetConfig
418 \brief API to change the current Bluetooth Coexistence (BTC) configuration
419 This function should be invoked only after CFG download has completed.
420 \param hHal - The handle returned by macOpen.
421 \param pSmeBtcConfig - Pointer to a caller allocated object of type
422 tSmeBtcConfig. Caller owns the memory and is responsible
423 for freeing it.
424 \return VOS_STATUS
425 VOS_STATUS_E_FAILURE Config not passed to HAL.
426 VOS_STATUS_SUCCESS Config passed to HAL
427 ---------------------------------------------------------------------------*/
428VOS_STATUS btcSetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig)
429{
430 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
431 //Save a copy in the global BTC config
432 vos_mem_copy(&(pMac->btc.btcConfig), pSmeBtcConfig, sizeof(tSmeBtcConfig));
433 //Send the config down only if SME_HddReady has been invoked. If not ready,
434 //BTC config will plumbed down when btcReady is eventually invoked.
435 if(pMac->btc.btcReady)
436 {
437 if(VOS_STATUS_SUCCESS != btcSendCfgMsg(hHal, pSmeBtcConfig))
438 {
439 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_FATAL,
440 "Failure to send BTC config down");
441 return VOS_STATUS_E_FAILURE;
442 }
443 }
444 return VOS_STATUS_SUCCESS;
445}
446/* ---------------------------------------------------------------------------
447 \fn btcPostBtcCfgMsg
448 \brief Private API to post BTC config message to HAL
449 \param hHal - The handle returned by macOpen.
450 \param pSmeBtcConfig - Pointer to a caller allocated object of type
451 tSmeBtcConfig. Caller owns the memory and is responsible
452 for freeing it.
453 \return VOS_STATUS
454 VOS_STATUS_E_FAILURE Config not passed to HAL.
455 VOS_STATUS_SUCCESS Config passed to HAL
456 ---------------------------------------------------------------------------*/
457VOS_STATUS btcSendCfgMsg(tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig)
458{
459 tpSmeBtcConfig ptrSmeBtcConfig = NULL;
460 vos_msg_t msg;
461 if( NULL == pSmeBtcConfig )
462 {
463 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: "
464 "Null pointer for BTC Config");
465 return VOS_STATUS_E_FAILURE;
466 }
467 if( pSmeBtcConfig->btcExecutionMode >= BT_EXEC_MODE_MAX )
468 {
469 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: "
470 "Invalid BT execution mode %d being set",
471 pSmeBtcConfig->btcExecutionMode);
472 return VOS_STATUS_E_FAILURE;
473 }
474 ptrSmeBtcConfig = vos_mem_malloc(sizeof(tSmeBtcConfig));
475 if (NULL == ptrSmeBtcConfig)
476 {
477 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: "
478 "Not able to allocate memory for SME BTC Config");
479 return VOS_STATUS_E_FAILURE;
480 }
481 vos_mem_copy(ptrSmeBtcConfig, pSmeBtcConfig, sizeof(tSmeBtcConfig));
482 msg.type = WDA_BTC_SET_CFG;
483 msg.reserved = 0;
484 msg.bodyptr = ptrSmeBtcConfig;
485 if(VOS_STATUS_SUCCESS != vos_mq_post_message(VOS_MODULE_ID_WDA, &msg))
486 {
487 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcSendCfgMsg: "
488 "Not able to post WDA_BTC_SET_CFG message to WDA");
489 vos_mem_free( ptrSmeBtcConfig );
490 return VOS_STATUS_E_FAILURE;
491 }
492 return VOS_STATUS_SUCCESS;
493}
494/* ---------------------------------------------------------------------------
495 \fn btcGetConfig
496 \brief API to retrieve the current Bluetooth Coexistence (BTC) configuration
497 \param hHal - The handle returned by macOpen.
498 \param pSmeBtcConfig - Pointer to a caller allocated object of type
499 tSmeBtcConfig. Caller owns the memory and is responsible
500 for freeing it.
501 \return VOS_STATUS
502 VOS_STATUS_E_FAILURE - failure
503 VOS_STATUS_SUCCESS success
504 ---------------------------------------------------------------------------*/
505VOS_STATUS btcGetConfig (tHalHandle hHal, tpSmeBtcConfig pSmeBtcConfig)
506{
507 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
508 if( NULL == pSmeBtcConfig )
509 {
510 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "btcGetConfig: "
511 "Null pointer for BTC Config");
512 return VOS_STATUS_E_FAILURE;
513 }
514 vos_mem_copy(pSmeBtcConfig, &(pMac->btc.btcConfig), sizeof(tSmeBtcConfig));
515 return VOS_STATUS_SUCCESS;
516}
517/*
518 btcFindAclEventHist find a suited ACL event buffer
519 Param: bdAddr - NULL meaning not care.
520 pointer to caller alocated buffer containing the BD address to find a match
521 handle - BT_INVALID_CONN_HANDLE == not care
522 otherwise, a handle to match
523 NOPTE: Either bdAddr or handle can be valid, if both of them are valid, use bdAddr only. If neither
524 bdAddr nor handle is valid, return the next free slot.
525*/
526static tpSmeBtAclEventHist btcFindAclEventHist( tpAniSirGlobal pMac, v_U8_t *bdAddr, v_U16_t handle )
527{
528 int i, j;
529 tpSmeBtAclEventHist pRet = NULL;
530 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
531 for( i = 0; (i < BT_MAX_ACL_SUPPORT) && (NULL == pRet); i++ )
532 {
533 if( NULL != bdAddr )
534 {
535 //try to match addr
536 if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx )
537 {
538 for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++)
539 {
540 if( vos_mem_compare(pReplay->btcEventHist.btAclConnectionEvent[i].btAclConnection[j].bdAddr,
541 bdAddr, 6) )
542 {
543 //found it
544 pRet = &pReplay->btcEventHist.btAclConnectionEvent[i];
545 break;
546 }
547 }
548 }
549 }
550 else if( BT_INVALID_CONN_HANDLE != handle )
551 {
552 //try to match handle
553 if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx )
554 {
555 for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++)
556 {
557 if( pReplay->btcEventHist.btAclConnectionEvent[i].btAclConnection[j].connectionHandle ==
558 handle )
559 {
560 //found it
561 pRet = &pReplay->btcEventHist.btAclConnectionEvent[i];
562 break;
563 }
564 }
565 }
566 }
567 else if( 0 == pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx )
568 {
569 pRet = &pReplay->btcEventHist.btAclConnectionEvent[i];
570 break;
571 }
572 }
573 return (pRet);
574}
575
576/*
577 btcFindSyncEventHist find a suited SYNC event buffer
578 Param: bdAddr - NULL meaning not care.
579 pointer to caller alocated buffer containing the BD address to find a match
580 handle - BT_INVALID_CONN_HANDLE == not care
581 otherwise, a handle to match
582 NOPTE: Either bdAddr or handle can be valid, if both of them are valid, use bdAddr only. If neither
583 bdAddr nor handle is valid, return the next free slot.
584*/
585static tpSmeBtSyncEventHist btcFindSyncEventHist( tpAniSirGlobal pMac, v_U8_t *bdAddr, v_U16_t handle )
586{
587 int i, j;
588 tpSmeBtSyncEventHist pRet = NULL;
589 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
590 for( i = 0; (i < BT_MAX_SCO_SUPPORT) && (NULL == pRet); i++ )
591 {
592 if( NULL != bdAddr )
593 {
594 //try to match addr
595 if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx )
596 {
597 for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++)
598 {
599 if( vos_mem_compare(pReplay->btcEventHist.btSyncConnectionEvent[i].btSyncConnection[j].bdAddr,
600 bdAddr, 6) )
601 {
602 //found it
603 pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i];
604 break;
605 }
606 }
607 }
608 }
609 else if( BT_INVALID_CONN_HANDLE != handle )
610 {
611 //try to match handle
612 if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx )
613 {
614 for(j = 0; j < pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx; j++)
615 {
616 if( pReplay->btcEventHist.btSyncConnectionEvent[i].btSyncConnection[j].connectionHandle ==
617 handle )
618 {
619 //found it
620 pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i];
621 break;
622 }
623 }
624 }
625 }
626 else if( !pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx )
627 {
628 pRet = &pReplay->btcEventHist.btSyncConnectionEvent[i];
629 break;
630 }
631 }
632 return (pRet);
633}
634
635/*
636 btcFindDisconnEventHist find a slot for the deferred disconnect event
637 If handle is invlid, it returns a free slot, if any.
638 If handle is valid, it tries to find a match first in case same disconnect event comes down again.
639*/
640static tpSmeBtDisconnectEventHist btcFindDisconnEventHist( tpAniSirGlobal pMac, v_U16_t handle )
641{
642 tpSmeBtDisconnectEventHist pRet = NULL;
643 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
644 int i;
645 if( BT_INVALID_CONN_HANDLE != handle )
646 {
647 for(i = 0; i < BT_MAX_DISCONN_SUPPORT; i++)
648 {
649 if( pReplay->btcEventHist.btDisconnectEvent[i].fValid &&
650 (handle == pReplay->btcEventHist.btDisconnectEvent[i].btDisconnect.connectionHandle) )
651 {
652 pRet = &pReplay->btcEventHist.btDisconnectEvent[i];
653 break;
654 }
655 }
656 }
657 if( NULL == pRet )
658 {
659 //Find a free slot
660 for(i = 0; i < BT_MAX_DISCONN_SUPPORT; i++)
661 {
662 if( !pReplay->btcEventHist.btDisconnectEvent[i].fValid )
663 {
664 pRet = &pReplay->btcEventHist.btDisconnectEvent[i];
665 break;
666 }
667 }
668 }
669 return (pRet);
670}
671
672/*
673 btcFindModeChangeEventHist find a slot for the deferred mopde change event
674 If handle is invalid, it returns a free slot, if any.
675 If handle is valid, it tries to find a match first in case same disconnect event comes down again.
676*/
677tpSmeBtAclModeChangeEventHist btcFindModeChangeEventHist( tpAniSirGlobal pMac, v_U16_t handle )
678{
679 tpSmeBtAclModeChangeEventHist pRet = NULL;
680 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
681 int i;
682 if( BT_INVALID_CONN_HANDLE != handle )
683 {
684 for(i = 0; i < BT_MAX_ACL_SUPPORT; i++)
685 {
686 if( pReplay->btcEventHist.btAclModeChangeEvent[i].fValid &&
687 (handle == pReplay->btcEventHist.btAclModeChangeEvent[i].btAclModeChange.connectionHandle) )
688 {
689 pRet = &pReplay->btcEventHist.btAclModeChangeEvent[i];
690 break;
691 }
692 }
693 }
694 if( NULL == pRet )
695 {
696 //Find a free slot
697 for(i = 0; i < BT_MAX_ACL_SUPPORT; i++)
698 {
699 if( !pReplay->btcEventHist.btAclModeChangeEvent[i].fValid )
700 {
701 pRet = &pReplay->btcEventHist.btAclModeChangeEvent[i];
702 break;
703 }
704 }
705 }
706 return (pRet);
707}
708
709/*
710 btcFindSyncUpdateEventHist find a slot for the deferred SYNC_UPDATE event
711 If handle is invalid, it returns a free slot, if any.
712 If handle is valid, it tries to find a match first in case same disconnect event comes down again.
713*/
714tpSmeBtSyncUpdateHist btcFindSyncUpdateEventHist( tpAniSirGlobal pMac, v_U16_t handle )
715{
716 tpSmeBtSyncUpdateHist pRet = NULL;
717 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
718 int i;
719 if( BT_INVALID_CONN_HANDLE != handle )
720 {
721 for(i = 0; i < BT_MAX_SCO_SUPPORT; i++)
722 {
723 if( pReplay->btcEventHist.btSyncUpdateEvent[i].fValid &&
724 (handle == pReplay->btcEventHist.btSyncUpdateEvent[i].btSyncConnection.connectionHandle) )
725 {
726 pRet = &pReplay->btcEventHist.btSyncUpdateEvent[i];
727 break;
728 }
729 }
730 }
731 if( NULL == pRet )
732 {
733 //Find a free slot
734 for(i = 0; i < BT_MAX_SCO_SUPPORT; i++)
735 {
736 if( !pReplay->btcEventHist.btSyncUpdateEvent[i].fValid )
737 {
738 pRet = &pReplay->btcEventHist.btSyncUpdateEvent[i];
739 break;
740 }
741 }
742 }
743 return (pRet);
744}
745
746/*
747 Call must validate pAclEventHist
748*/
749static void btcReleaseAclEventHist( tpAniSirGlobal pMac, tpSmeBtAclEventHist pAclEventHist )
750{
751 vos_mem_zero( pAclEventHist, sizeof(tSmeBtAclEventHist) );
752}
753
754/*
755 Call must validate pSyncEventHist
756*/
757static void btcReleaseSyncEventHist( tpAniSirGlobal pMac, tpSmeBtSyncEventHist pSyncEventHist )
758{
759 vos_mem_zero( pSyncEventHist, sizeof(tSmeBtSyncEventHist) );
760}
761
762/*To defer a ACL creation event
763 We only support one ACL per BD address.
764 If the last cached event another ACL create event, replace that event with the new event
765 If a completion event with success status code, and the new ACL creation
766 on same address, defer a new disconnect event(fake one), then cache this ACL creation event.
767 Otherwise, save this create event.
768*/
769static VOS_STATUS btcDeferAclCreate( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
770{
771 VOS_STATUS status = VOS_STATUS_SUCCESS;
772 tpSmeBtAclEventHist pAclEventHist;
773 tSmeBtAclConnectionParam *pAclEvent;
774 do
775 {
776 //Find a match
777 pAclEventHist = btcFindAclEventHist( pMac, pEvent->uEventParam.btAclConnection.bdAddr,
778 BT_INVALID_CONN_HANDLE );
779 if( NULL == pAclEventHist )
780 {
781 //No cached ACL event on this address
782 //Find a free slot and save it
783 pAclEventHist = btcFindAclEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE );
784 if( NULL != pAclEventHist )
785 {
786 vos_mem_copy(&pAclEventHist->btAclConnection[0], &pEvent->uEventParam.btAclConnection,
787 sizeof(tSmeBtAclConnectionParam));
788 pAclEventHist->btEventType[0] = BT_EVENT_CREATE_ACL_CONNECTION;
789 pAclEventHist->bNextEventIdx = 1;
790 }
791 else
792 {
793 smsLog(pMac, LOGE, FL(" failed to find ACL event slot\n"));
794 status = VOS_STATUS_E_RESOURCES;
795 }
796 //done
797 break;
798 }
799 else
800 {
801 //There is history on this BD address
802 VOS_ASSERT(pAclEventHist->bNextEventIdx > 0);
803 pAclEvent = &pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx - 1];
804 if(BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[pAclEventHist->bNextEventIdx - 1])
805 {
806 //The last cached event is creation, replace it with the new one
807 vos_mem_copy(pAclEvent,
808 &pEvent->uEventParam.btAclConnection,
809 sizeof(tSmeBtAclConnectionParam));
810 //done
811 break;
812 }
813 else if(BT_EVENT_ACL_CONNECTION_COMPLETE ==
814 pAclEventHist->btEventType[pAclEventHist->bNextEventIdx - 1])
815 {
816 //The last cached event is completion, check the status.
817 if(BT_CONN_STATUS_SUCCESS == pAclEvent->status)
818 {
819 tSmeBtEvent btEvent;
820 //The last event we have is success completion event.
821 //Should not get a creation event before creation.
822 smsLog(pMac, LOGE, FL(" Missing disconnect event on handle %d\n"), pAclEvent->connectionHandle);
823 //Fake a disconnect event
824 btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE;
825 btEvent.uEventParam.btDisconnect.connectionHandle = pAclEvent->connectionHandle;
826 btcDeferDisconnEvent(pMac, &btEvent);
827 }
828 }
829 //Need to save the new event
830 if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED)
831 {
832 pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] = BT_EVENT_CREATE_ACL_CONNECTION;
833 vos_mem_copy(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx],
834 &pEvent->uEventParam.btAclConnection,
835 sizeof(tSmeBtAclConnectionParam));
836 pAclEventHist->bNextEventIdx++;
837 }
838 else
839 {
840 smsLog(pMac, LOGE, FL(" ACL event overflow\n"));
841 VOS_ASSERT(0);
842 }
843 }
844 }while(0);
845 return status;
846}
847
848/*Defer a ACL completion event
849 If there is cached event on this BD address, check completion status.
850 If status is fail and last cached event is creation, remove the creation event and drop
851 this completion event. Otherwise, cache this completion event as the latest one.
852*/
853static VOS_STATUS btcDeferAclComplete( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
854{
855 VOS_STATUS status = VOS_STATUS_SUCCESS;
856 tpSmeBtAclEventHist pAclEventHist;
857 do
858 {
859 //Find a match
860 pAclEventHist = btcFindAclEventHist( pMac, pEvent->uEventParam.btAclConnection.bdAddr,
861 BT_INVALID_CONN_HANDLE );
862 if(pAclEventHist)
863 {
864 VOS_ASSERT(pAclEventHist->bNextEventIdx >0);
865 //Found one
866 if(BT_CONN_STATUS_SUCCESS != pEvent->uEventParam.btAclConnection.status)
867 {
868 //If completion fails, and the last one is creation, remove the creation event
869 if(BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[pAclEventHist->bNextEventIdx-1])
870 {
871 vos_mem_zero(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx-1],
872 sizeof(tSmeBtAclConnectionParam));
873 pAclEventHist->bNextEventIdx--;
874 //Done with this event
875 break;
876 }
877 else
878 {
879 smsLog(pMac, LOGE, FL(" ACL completion fail but last event(%d) not creation\n"),
880 pAclEventHist->btEventType[pAclEventHist->bNextEventIdx-1]);
881 }
882 }
883 }
884 if( NULL == pAclEventHist )
885 {
886 pAclEventHist = btcFindAclEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE );
887 }
888 if(pAclEventHist)
889 {
890 if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED)
891 {
892 //Save this event
893 pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] = BT_EVENT_ACL_CONNECTION_COMPLETE;
894 vos_mem_copy(&pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx],
895 &pEvent->uEventParam.btAclConnection,
896 sizeof(tSmeBtAclConnectionParam));
897 pAclEventHist->bNextEventIdx++;
898 }
899 else
900 {
901 smsLog(pMac, LOGE, FL(" ACL event overflow\n"));
902 VOS_ASSERT(0);
903 }
904 }
905 else
906 {
907 smsLog( pMac, LOGE, FL(" cannot find match for failed BT_EVENT_ACL_CONNECTION_COMPLETE of bdAddr (%02X-%02X-%02X-%02X-%02X-%02X)\n"),
908 pEvent->uEventParam.btAclConnection.bdAddr[0],
909 pEvent->uEventParam.btAclConnection.bdAddr[1],
910 pEvent->uEventParam.btAclConnection.bdAddr[2],
911 pEvent->uEventParam.btAclConnection.bdAddr[3],
912 pEvent->uEventParam.btAclConnection.bdAddr[4],
913 pEvent->uEventParam.btAclConnection.bdAddr[5]);
914 status = VOS_STATUS_E_EMPTY;
915 }
916 }while(0);
917 return (status);
918}
919
920/*To defer a SYNC creation event
921 If the last cached event is another SYNC create event, replace
922 that event with the new event.
923 If there is a completion event with success status code, cache a new
924 disconnect event(fake) first, then cache this SYNC creation event.
925 Otherwise, cache this create event.
926*/
927static VOS_STATUS btcDeferSyncCreate( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
928{
929 VOS_STATUS status = VOS_STATUS_SUCCESS;
930 tpSmeBtSyncEventHist pSyncEventHist;
931 tSmeBtSyncConnectionParam *pSyncEvent;
932 do
933 {
934 //Find a match
935 pSyncEventHist = btcFindSyncEventHist( pMac, pEvent->uEventParam.btSyncConnection.bdAddr,
936 BT_INVALID_CONN_HANDLE );
937 if( NULL == pSyncEventHist )
938 {
939 //No cached ACL event on this address
940 //Find a free slot and save it
941 pSyncEventHist = btcFindSyncEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE );
942 if( NULL != pSyncEventHist )
943 {
944 vos_mem_copy(&pSyncEventHist->btSyncConnection[0], &pEvent->uEventParam.btSyncConnection,
945 sizeof(tSmeBtSyncConnectionParam));
946 pSyncEventHist->btEventType[0] = BT_EVENT_CREATE_SYNC_CONNECTION;
947 pSyncEventHist->bNextEventIdx = 1;
948 }
949 else
950 {
951 smsLog(pMac, LOGE, FL(" failed to find SYNC event slot\n"));
952 status = VOS_STATUS_E_RESOURCES;
953 }
954 //done
955 break;
956 }
957 else
958 {
959 //There is history on this BD address
960 VOS_ASSERT(pSyncEventHist->bNextEventIdx > 0);
961 pSyncEvent = &pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx - 1];
962 if(BT_EVENT_CREATE_SYNC_CONNECTION ==
963 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx - 1])
964 {
965 //The last cached event is creation, replace it with the new one
966 vos_mem_copy(pSyncEvent,
967 &pEvent->uEventParam.btSyncConnection,
968 sizeof(tSmeBtSyncConnectionParam));
969 //done
970 break;
971 }
972 else if(BT_EVENT_SYNC_CONNECTION_COMPLETE ==
973 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx - 1])
974 {
975 //The last cached event is completion, check the status.
976 if(BT_CONN_STATUS_SUCCESS == pSyncEvent->status)
977 {
978 tSmeBtEvent btEvent;
979 //The last event we have is success completion event.
980 //Should not get a creation event before creation.
981 smsLog(pMac, LOGE, FL(" Missing disconnect event on handle %d\n"), pSyncEvent->connectionHandle);
982 //Fake a disconnect event
983 btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE;
984 btEvent.uEventParam.btDisconnect.connectionHandle = pSyncEvent->connectionHandle;
985 btcDeferDisconnEvent(pMac, &btEvent);
986 }
987 }
988 //Need to save the new event
989 if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_SCO_DEFERRED)
990 {
991 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] = BT_EVENT_CREATE_SYNC_CONNECTION;
992 vos_mem_copy(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx],
993 &pEvent->uEventParam.btSyncConnection,
994 sizeof(tSmeBtSyncConnectionParam));
995 pSyncEventHist->bNextEventIdx++;
996 }
997 else
998 {
999 smsLog(pMac, LOGE, FL(" SYNC event overflow\n"));
1000 }
1001 }
1002 }while(0);
1003 return status;
1004}
1005
1006/*Defer a SYNC completion event
1007 If there is cached event on this BD address, check completion status.
1008 If status is fail and last cached event is creation, remove te creation event and drop
1009 this completion event.
1010 Otherwise, cache this completion event as the latest one.
1011*/
1012static VOS_STATUS btcDeferSyncComplete( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
1013{
1014 VOS_STATUS status = VOS_STATUS_SUCCESS;
1015 tpSmeBtSyncEventHist pSyncEventHist;
1016 do
1017 {
1018 //Find a match
1019 pSyncEventHist = btcFindSyncEventHist( pMac, pEvent->uEventParam.btSyncConnection.bdAddr,
1020 BT_INVALID_CONN_HANDLE );
1021 if(pSyncEventHist)
1022 {
1023 VOS_ASSERT(pSyncEventHist->bNextEventIdx >0);
1024 //Found one
1025 if(BT_CONN_STATUS_SUCCESS != pEvent->uEventParam.btSyncConnection.status)
1026 {
1027 //If completion fails, and the last one is creation, remove the creation event
1028 if(BT_EVENT_CREATE_SYNC_CONNECTION == pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx-1])
1029 {
1030 vos_mem_zero(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx-1],
1031 sizeof(tSmeBtSyncConnectionParam));
1032 pSyncEventHist->bNextEventIdx--;
1033 //Done with this event
1034 break;
1035 }
1036 else
1037 {
1038 smsLog(pMac, LOGE, FL(" SYNC completion fail but last event(%d) not creation\n"),
1039 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx-1]);
1040 }
1041 }
1042 }
1043 if(NULL == pSyncEventHist)
1044 {
1045 //In case we don't defer the creation event
1046 pSyncEventHist = btcFindSyncEventHist( pMac, NULL, BT_INVALID_CONN_HANDLE );
1047 }
1048 if(pSyncEventHist)
1049 {
1050 if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED)
1051 {
1052 //Save this event
1053 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] = BT_EVENT_SYNC_CONNECTION_COMPLETE;
1054 vos_mem_copy(&pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx],
1055 &pEvent->uEventParam.btSyncConnection,
1056 sizeof(tSmeBtSyncConnectionParam));
1057 pSyncEventHist->bNextEventIdx++;
1058 }
1059 else
1060 {
1061 smsLog(pMac, LOGE, FL(" SYNC event overflow\n"));
1062 }
1063 }
1064 else
1065 {
1066 smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_SYNC_CONNECTION_COMPLETE of bdAddr (%02X-%02X-%02X-%02X-%02X-%02X)\n"),
1067 pEvent->uEventParam.btSyncConnection.bdAddr[0],
1068 pEvent->uEventParam.btSyncConnection.bdAddr[1],
1069 pEvent->uEventParam.btSyncConnection.bdAddr[2],
1070 pEvent->uEventParam.btSyncConnection.bdAddr[3],
1071 pEvent->uEventParam.btSyncConnection.bdAddr[4],
1072 pEvent->uEventParam.btSyncConnection.bdAddr[5]);
1073 status = VOS_STATUS_E_EMPTY;
1074 }
1075 }while(0);
1076 return (status);
1077}
1078
1079//return VOS_STATUS_E_EXISTS if the event handle cannot be found
1080//VOS_STATUS_SUCCESS if the event is processed
1081//Other error status meaning it cannot continue due to other errors
1082/*
1083 Defer a disconnect event for ACL
1084 Check if any history on this event handle.
1085 If both ACL_CREATION and ACL_COMPLETION is cached, remove both those events and drop
1086 this disconnect event.
1087 Otherwise save disconnect event in this ACL's bin.
1088 If not ACL match on this handle, not to do anything.
1089 Either way, remove any cached MODE_CHANGE event matches this disconnect event's handle.
1090*/
1091static VOS_STATUS btcDeferDisconnectEventForACL( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
1092{
1093 VOS_STATUS status = VOS_STATUS_SUCCESS;
1094 tpSmeBtAclEventHist pAclEventHist;
1095 tpSmeBtAclModeChangeEventHist pModeChangeEventHist;
1096 v_BOOL_t fDone = VOS_FALSE;
1097 int i;
1098 pAclEventHist = btcFindAclEventHist( pMac, NULL,
1099 pEvent->uEventParam.btDisconnect.connectionHandle );
1100 if(pAclEventHist)
1101 {
1102 if( pAclEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_ACL_DEFERRED)
1103 {
1104 smsLog(pMac, LOGE, FL(" ACL event history index:%d overflow, resetting to BT_MAX_NUM_EVENT_ACL_DEFERRED\n"), pAclEventHist->bNextEventIdx);
1105 pAclEventHist->bNextEventIdx = BT_MAX_NUM_EVENT_ACL_DEFERRED;
1106 }
1107 //Looking backwords
1108 for(i = pAclEventHist->bNextEventIdx - 1; i >= 0; i--)
1109 {
1110 if( BT_EVENT_ACL_CONNECTION_COMPLETE == pAclEventHist->btEventType[i] )
1111 {
1112 //make sure we can cancel the link
1113 if( (i > 0) && (BT_EVENT_CREATE_ACL_CONNECTION == pAclEventHist->btEventType[i - 1]) )
1114 {
1115 fDone = VOS_TRUE;
1116 if(i == 1)
1117 {
1118 //All events can be wiped off
1119 btcReleaseAclEventHist(pMac, pAclEventHist);
1120 break;
1121 }
1122 //we have both ACL creation and completion, wipe out all of them
1123 pAclEventHist->bNextEventIdx = (tANI_U8)(i - 1);
1124 vos_mem_zero(&pAclEventHist->btAclConnection[i-1], sizeof(tSmeBtAclConnectionParam));
1125 vos_mem_zero(&pAclEventHist->btAclConnection[i], sizeof(tSmeBtAclConnectionParam));
1126 break;
1127 }
1128 }
1129 }//for loop
1130 if(!fDone)
1131 {
1132 //Save this disconnect event
1133 if(pAclEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_ACL_DEFERRED)
1134 {
1135 pAclEventHist->btEventType[pAclEventHist->bNextEventIdx] =
1136 BT_EVENT_DISCONNECTION_COMPLETE;
1137 pAclEventHist->btAclConnection[pAclEventHist->bNextEventIdx].connectionHandle =
1138 pEvent->uEventParam.btDisconnect.connectionHandle;
1139 pAclEventHist->bNextEventIdx++;
1140 }
1141 else
1142 {
1143 smsLog(pMac, LOGE, FL(" ACL event overflow\n"));
1144 status = VOS_STATUS_E_FAILURE;
1145 }
1146 }
1147 }
1148 else
1149 {
1150 status = VOS_STATUS_E_EXISTS;
1151 }
1152 //Wipe out the related mode change event if it is there
1153 pModeChangeEventHist = btcFindModeChangeEventHist( pMac,
1154 pEvent->uEventParam.btDisconnect.connectionHandle );
1155 if( pModeChangeEventHist && pModeChangeEventHist->fValid )
1156 {
1157 pModeChangeEventHist->fValid = VOS_FALSE;
1158 }
1159 return status;
1160}
1161
1162//This function works the same as btcDeferDisconnectEventForACL except it hanldes SYNC events
1163//return VOS_STATUS_E_EXISTS if the event handle cannot be found
1164//VOS_STATUS_SUCCESS if the event is processed
1165//Other error status meaning it cannot continue due to other errors
1166/*
1167 Defer a disconnect event for SYNC
1168 Check if any SYNC history on this event handle.
1169 If yes and if both SYNC_CREATION and SYNC_COMPLETION is cached, remove both those events and drop
1170 this disconnect event.
1171 Otherwise save disconnect event in this SYNC's bin.
1172 If no match found, not to save this event here.
1173 Either way, remove any cached SYNC_UPDATE event matches this disconnect event's handle.
1174*/
1175static VOS_STATUS btcDeferDisconnectEventForSync( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
1176{
1177 VOS_STATUS status = VOS_STATUS_SUCCESS;
1178 tpSmeBtSyncEventHist pSyncEventHist;
1179 tpSmeBtSyncUpdateHist pSyncUpdateHist;
1180 v_BOOL_t fDone = VOS_FALSE;
1181 int i;
1182 pSyncEventHist = btcFindSyncEventHist( pMac, NULL,
1183 pEvent->uEventParam.btDisconnect.connectionHandle );
1184 if(pSyncEventHist)
1185 {
1186 if( pSyncEventHist->bNextEventIdx > BT_MAX_NUM_EVENT_SCO_DEFERRED)
1187 {
1188 smsLog(pMac, LOGE, FL(" SYNC event history index:%d overflow, resetting to BT_MAX_NUM_EVENT_SCO_DEFERRED\n"), pSyncEventHist->bNextEventIdx);
1189 pSyncEventHist->bNextEventIdx = BT_MAX_NUM_EVENT_SCO_DEFERRED;
1190 }
1191 //Looking backwords
1192 for(i = pSyncEventHist->bNextEventIdx - 1; i >= 0; i--)
1193 {
1194 //if a mode change event exists, drop it
1195 if( BT_EVENT_SYNC_CONNECTION_COMPLETE == pSyncEventHist->btEventType[i] )
1196 {
1197 //make sure we can cancel the link
1198 if( (i > 0) && (BT_EVENT_CREATE_SYNC_CONNECTION == pSyncEventHist->btEventType[i - 1]) )
1199 {
1200 fDone = VOS_TRUE;
1201 if(i == 1)
1202 {
1203 //All events can be wiped off
1204 btcReleaseSyncEventHist(pMac, pSyncEventHist);
1205 break;
1206 }
1207 //we have both ACL creation and completion, wipe out all of them
1208 pSyncEventHist->bNextEventIdx = (tANI_U8)(i - 1);
1209 vos_mem_zero(&pSyncEventHist->btSyncConnection[i-1], sizeof(tSmeBtSyncConnectionParam));
1210 vos_mem_zero(&pSyncEventHist->btSyncConnection[i], sizeof(tSmeBtSyncConnectionParam));
1211 break;
1212 }
1213 }
1214 }//for loop
1215 if(!fDone)
1216 {
1217 //Save this disconnect event
1218 if(pSyncEventHist->bNextEventIdx < BT_MAX_NUM_EVENT_SCO_DEFERRED)
1219 {
1220 pSyncEventHist->btEventType[pSyncEventHist->bNextEventIdx] =
1221 BT_EVENT_DISCONNECTION_COMPLETE;
1222 pSyncEventHist->btSyncConnection[pSyncEventHist->bNextEventIdx].connectionHandle =
1223 pEvent->uEventParam.btDisconnect.connectionHandle;
1224 pSyncEventHist->bNextEventIdx++;
1225 }
1226 else
1227 {
1228 smsLog(pMac, LOGE, FL(" SYNC event overflow\n"));
1229 status = VOS_STATUS_E_FAILURE;
1230 }
1231 }
1232 }
1233 else
1234 {
1235 status = VOS_STATUS_E_EXISTS;
1236 }
1237 //Wipe out the related mode change event if it is there
1238 pSyncUpdateHist = btcFindSyncUpdateEventHist( pMac,
1239 pEvent->uEventParam.btDisconnect.connectionHandle );
1240 if( pSyncUpdateHist && pSyncUpdateHist->fValid )
1241 {
1242 pSyncUpdateHist->fValid = VOS_FALSE;
1243 }
1244 return status;
1245}
1246
1247/*
1248 Defer a disconnect event.
1249 Try to defer it as part of the ACL event first.
1250 If no match is found, try SYNC.
1251 If still no match found, defer it at DISCONNECT event bin.
1252*/
1253static VOS_STATUS btcDeferDisconnEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
1254{
1255 VOS_STATUS status = VOS_STATUS_SUCCESS;
1256 tpSmeBtDisconnectEventHist pDisconnEventHist;
1257 if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle )
1258 {
1259 smsLog( pMac, LOGE, FL(" invalid handle\n") );
1260 return (VOS_STATUS_E_INVAL);
1261 }
1262 //Check ACL first
1263 status = btcDeferDisconnectEventForACL(pMac, pEvent);
1264 if(!VOS_IS_STATUS_SUCCESS(status))
1265 {
1266 status = btcDeferDisconnectEventForSync(pMac, pEvent);
1267 }
1268 if( !VOS_IS_STATUS_SUCCESS(status) )
1269 {
1270 //Save the disconnect event
1271 pDisconnEventHist = btcFindDisconnEventHist( pMac,
1272 pEvent->uEventParam.btDisconnect.connectionHandle );
1273 if( pDisconnEventHist )
1274 {
1275 pDisconnEventHist->fValid = VOS_TRUE;
1276 vos_mem_copy( &pDisconnEventHist->btDisconnect, &pEvent->uEventParam.btDisconnect,
1277 sizeof(tSmeBtDisconnectParam) );
1278 status = VOS_STATUS_SUCCESS;
1279 }
1280 else
1281 {
1282 smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_DISCONNECTION_COMPLETE of handle (%d)\n"),
1283 pEvent->uEventParam.btDisconnect.connectionHandle);
1284 status = VOS_STATUS_E_EMPTY;
1285 }
1286 }
1287 return (status);
1288}
1289
1290/*
1291 btcDeferEvent save the event for possible replay when chip can be accessed
1292 This function is called only when in IMPS/Standby state
1293*/
1294static VOS_STATUS btcDeferEvent( tpAniSirGlobal pMac, tpSmeBtEvent pEvent )
1295{
1296 VOS_STATUS status = VOS_STATUS_SUCCESS;
1297 tpSmeBtSyncUpdateHist pSyncUpdateHist;
1298 tpSmeBtAclModeChangeEventHist pModeChangeEventHist;
1299 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
1300 switch(pEvent->btEventType)
1301 {
1302 case BT_EVENT_DEVICE_SWITCHED_ON:
1303 //Clear all events first
1304 vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) );
1305 pReplay->fBTSwitchOn = VOS_TRUE;
1306 pReplay->fBTSwitchOff = VOS_FALSE;
1307 break;
1308 case BT_EVENT_DEVICE_SWITCHED_OFF:
1309 //Clear all events first
1310 vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) );
1311 pReplay->fBTSwitchOff = VOS_TRUE;
1312 pReplay->fBTSwitchOn = VOS_FALSE;
1313 break;
1314 case BT_EVENT_INQUIRY_STARTED:
1315 pReplay->btcEventHist.nInquiryEvent++;
1316 break;
1317 case BT_EVENT_INQUIRY_STOPPED:
1318 pReplay->btcEventHist.nInquiryEvent--;
1319 break;
1320 case BT_EVENT_PAGE_STARTED:
1321 pReplay->btcEventHist.nPageEvent++;
1322 break;
1323 case BT_EVENT_PAGE_STOPPED:
1324 pReplay->btcEventHist.nPageEvent--;
1325 break;
1326 case BT_EVENT_CREATE_ACL_CONNECTION:
1327 status = btcDeferAclCreate(pMac, pEvent);
1328 break;
1329 case BT_EVENT_ACL_CONNECTION_COMPLETE:
1330 status = btcDeferAclComplete( pMac, pEvent );
1331 break;
1332 case BT_EVENT_CREATE_SYNC_CONNECTION:
1333 status = btcDeferSyncCreate(pMac, pEvent);
1334 break;
1335 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
1336 status = btcDeferSyncComplete( pMac, pEvent );
1337 break;
1338 case BT_EVENT_SYNC_CONNECTION_UPDATED:
1339 if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle )
1340 {
1341 smsLog( pMac, LOGE, FL(" invalid handle\n") );
1342 status = VOS_STATUS_E_INVAL;
1343 break;
1344 }
1345 //Find a match on handle. If not found, get a free slot.
1346 pSyncUpdateHist = btcFindSyncUpdateEventHist( pMac,
1347 pEvent->uEventParam.btSyncConnection.connectionHandle );
1348 if(pSyncUpdateHist)
1349 {
1350 pSyncUpdateHist->fValid = VOS_TRUE;
1351 vos_mem_copy(&pSyncUpdateHist->btSyncConnection, &pEvent->uEventParam.btSyncConnection,
1352 sizeof(tSmeBtSyncConnectionParam));
1353 }
1354 else
1355 {
1356 smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_SYNC_CONNECTION_UPDATED of handle (%d)\n"),
1357 pEvent->uEventParam.btSyncConnection.connectionHandle );
1358 status = VOS_STATUS_E_EMPTY;
1359 }
1360 break;
1361 case BT_EVENT_DISCONNECTION_COMPLETE:
1362 status = btcDeferDisconnEvent( pMac, pEvent );
1363 break;
1364 case BT_EVENT_MODE_CHANGED:
1365 if( BT_INVALID_CONN_HANDLE == pEvent->uEventParam.btDisconnect.connectionHandle )
1366 {
1367 smsLog( pMac, LOGE, FL(" invalid handle\n") );
1368 status = VOS_STATUS_E_INVAL;
1369 break;
1370 }
1371 //Find a match on handle, If not found, return a free slot
1372 pModeChangeEventHist = btcFindModeChangeEventHist( pMac,
1373 pEvent->uEventParam.btAclModeChange.connectionHandle );
1374 if(pModeChangeEventHist)
1375 {
1376 pModeChangeEventHist->fValid = VOS_TRUE;
1377 vos_mem_copy( &pModeChangeEventHist->btAclModeChange,
1378 &pEvent->uEventParam.btAclModeChange, sizeof(tSmeBtAclModeChangeParam) );
1379 }
1380 else
1381 {
1382 smsLog( pMac, LOGE, FL(" cannot find match for BT_EVENT_MODE_CHANGED of handle (%d)\n"),
1383 pEvent->uEventParam.btAclModeChange.connectionHandle);
1384 status = VOS_STATUS_E_EMPTY;
1385 }
1386 break;
1387 case BT_EVENT_A2DP_STREAM_START:
1388 pReplay->btcEventHist.fA2DPStarted = VOS_TRUE;
1389 pReplay->btcEventHist.fA2DPStopped = VOS_FALSE;
1390 break;
1391 case BT_EVENT_A2DP_STREAM_STOP:
1392 pReplay->btcEventHist.fA2DPStopped = VOS_TRUE;
1393 pReplay->btcEventHist.fA2DPStarted = VOS_FALSE;
1394 break;
1395 default:
1396 smsLog( pMac, LOGE, FL(" event (%d) is not deferred\n"), pEvent->btEventType );
1397 status = VOS_STATUS_E_NOSUPPORT;
1398 break;
1399 }
1400 return (status);
1401}
1402
1403/*
1404 Replay all cached events in the following order
1405 1. If BT_SWITCH_OFF event, send it.
1406 2. Send INQUIRY event (START or STOP),if available
1407 3. Send PAGE event (START or STOP), if available
1408 4. Send DISCONNECT events, these DISCONNECT events are not tied to
1409 any ACL/SYNC event that we have cached
1410 5. Send ACL events (possible events, CREATION, COMPLETION, DISCONNECT)
1411 6. Send MODE_CHANGE events, if available
1412 7. Send A2DP event(START or STOP), if available
1413 8. Send SYNC events (possible events, CREATION, COMPLETION, DISCONNECT)
1414 9. Send SYNC_UPDATE events, if available
1415*/
1416static void btcReplayEvents( tpAniSirGlobal pMac )
1417{
1418 int i, j;
1419 tSmeBtEvent btEvent;
1420 tpSmeBtAclEventHist pAclHist;
1421 tpSmeBtSyncEventHist pSyncHist;
1422 tSmeBtcEventReplay *pReplay = &pMac->btc.btcEventReplay;
1423 //Always turn on HB monitor first.
1424 //It is independent of BT events even though BT event causes this
1425 if( pReplay->fRestoreHBMonitor )
1426 {
1427 pReplay->fRestoreHBMonitor = VOS_FALSE;
1428 //Only do it when needed
1429 if( !pMac->btc.btcHBActive )
1430 {
1431 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE);
1432 pMac->btc.btcHBActive = VOS_TRUE;
1433 }
1434 }
1435 if( pMac->btc.fReplayBTEvents )
1436 {
1437 /*Set the flag to false here so btcSignalBTEvent won't defer any further.
1438 This works because SME has it global lock*/
1439 pMac->btc.fReplayBTEvents = VOS_FALSE;
1440 if( pReplay->fBTSwitchOff )
1441 {
1442 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1443 btEvent.btEventType = BT_EVENT_DEVICE_SWITCHED_OFF;
1444 btcSendBTEvent( pMac, &btEvent );
1445 pReplay->fBTSwitchOff = VOS_FALSE;
1446 }
1447 else if( pReplay->fBTSwitchOn )
1448 {
1449 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1450 btEvent.btEventType = BT_EVENT_DEVICE_SWITCHED_ON;
1451 btcSendBTEvent( pMac, &btEvent );
1452 pReplay->fBTSwitchOn = VOS_FALSE;
1453 }
1454 //Do inquire first
1455 if( pReplay->btcEventHist.nInquiryEvent > 0 )
1456 {
1457 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1458 btEvent.btEventType = BT_EVENT_INQUIRY_STARTED;
1459 i = pReplay->btcEventHist.nInquiryEvent;
1460 while(i--)
1461 {
1462 btcSendBTEvent( pMac, &btEvent );
1463 }
1464 }
1465 else if( pReplay->btcEventHist.nInquiryEvent < 0 )
1466 {
1467 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1468 btEvent.btEventType = BT_EVENT_INQUIRY_STOPPED;
1469 i = pReplay->btcEventHist.nInquiryEvent;
1470 while(i++)
1471 {
1472 btcSendBTEvent( pMac, &btEvent );
1473 }
1474 }
1475 //Page
1476 if( pReplay->btcEventHist.nPageEvent > 0 )
1477 {
1478 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1479 btEvent.btEventType = BT_EVENT_PAGE_STARTED;
1480 i = pReplay->btcEventHist.nPageEvent;
1481 while(i--)
1482 {
1483 btcSendBTEvent( pMac, &btEvent );
1484 }
1485 }
1486 else if( pReplay->btcEventHist.nPageEvent < 0 )
1487 {
1488 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1489 btEvent.btEventType = BT_EVENT_PAGE_STOPPED;
1490 i = pReplay->btcEventHist.nPageEvent;
1491 while(i++)
1492 {
1493 btcSendBTEvent( pMac, &btEvent );
1494 }
1495 }
1496 //Replay non-completion disconnect events first
1497 //Disconnect
1498 for( i = 0; i < BT_MAX_DISCONN_SUPPORT; i++ )
1499 {
1500 if( pReplay->btcEventHist.btDisconnectEvent[i].fValid )
1501 {
1502 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1503 btEvent.btEventType = BT_EVENT_DISCONNECTION_COMPLETE;
1504 vos_mem_copy( &btEvent.uEventParam.btDisconnect,
1505 &pReplay->btcEventHist.btDisconnectEvent[i].btDisconnect, sizeof(tSmeBtDisconnectParam) );
1506 btcSendBTEvent( pMac, &btEvent );
1507 }
1508 }
1509 //ACL
1510 for( i = 0; i < BT_MAX_ACL_SUPPORT; i++ )
1511 {
1512 if( pReplay->btcEventHist.btAclConnectionEvent[i].bNextEventIdx )
1513 {
1514 pAclHist = &pReplay->btcEventHist.btAclConnectionEvent[i];
1515 //Replay all ACL events for this BD address/handle
1516 for(j = 0; j < pAclHist->bNextEventIdx; j++)
1517 {
1518 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1519 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1520 btEvent.btEventType = pAclHist->btEventType[j];
1521 if(BT_EVENT_DISCONNECTION_COMPLETE != btEvent.btEventType)
1522 {
1523 //It must be CREATE or CONNECTION_COMPLETE
1524 vos_mem_copy( &btEvent.uEventParam.btAclConnection,
1525 &pAclHist->btAclConnection[j], sizeof(tSmeBtAclConnectionParam) );
1526 }
1527 else
1528 {
1529 btEvent.uEventParam.btDisconnect.connectionHandle = pAclHist->btAclConnection[j].connectionHandle;
1530 }
1531 btcSendBTEvent( pMac, &btEvent );
1532 }
1533 }
1534 }
1535 //Mode change
1536 for( i = 0; i < BT_MAX_ACL_SUPPORT; i++ )
1537 {
1538 if( pReplay->btcEventHist.btAclModeChangeEvent[i].fValid )
1539 {
1540 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1541 btEvent.btEventType = BT_EVENT_MODE_CHANGED;
1542 vos_mem_copy( &btEvent.uEventParam.btAclModeChange,
1543 &pReplay->btcEventHist.btAclModeChangeEvent[i].btAclModeChange, sizeof(tSmeBtAclModeChangeParam) );
1544 btcSendBTEvent( pMac, &btEvent );
1545 }
1546 }
1547 //A2DP
1548 if( pReplay->btcEventHist.fA2DPStarted )
1549 {
1550 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1551 btEvent.btEventType = BT_EVENT_A2DP_STREAM_START;
1552 btcSendBTEvent( pMac, &btEvent );
1553 }
1554 else if( pReplay->btcEventHist.fA2DPStopped )
1555 {
1556 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1557 btEvent.btEventType = BT_EVENT_A2DP_STREAM_STOP;
1558 btcSendBTEvent( pMac, &btEvent );
1559 }
1560 //SCO
1561 for( i = 0; i < BT_MAX_SCO_SUPPORT; i++ )
1562 {
1563 if( pReplay->btcEventHist.btSyncConnectionEvent[i].bNextEventIdx )
1564 {
1565 pSyncHist = &pReplay->btcEventHist.btSyncConnectionEvent[i];
1566 //Replay all SYNC events for this BD address/handle
1567 for(j = 0; j < pSyncHist->bNextEventIdx; j++)
1568 {
1569 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1570 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1571 btEvent.btEventType = pSyncHist->btEventType[j];
1572 if(BT_EVENT_DISCONNECTION_COMPLETE != btEvent.btEventType)
1573 {
1574 //Must be CREATION or CONNECTION_COMPLETE
1575 vos_mem_copy( &btEvent.uEventParam.btSyncConnection,
1576 &pSyncHist->btSyncConnection[j], sizeof(tSmeBtSyncConnectionParam) );
1577 }
1578 else
1579 {
1580 btEvent.uEventParam.btDisconnect.connectionHandle = pSyncHist->btSyncConnection[j].connectionHandle;
1581 }
1582 btcSendBTEvent( pMac, &btEvent );
1583 }
1584 }
1585 }
1586 //SYNC update
1587 for( i = 0; i < BT_MAX_SCO_SUPPORT; i++ )
1588 {
1589 if( pReplay->btcEventHist.btSyncUpdateEvent[i].fValid )
1590 {
1591 vos_mem_zero( &btEvent, sizeof(tSmeBtEvent) );
1592 btEvent.btEventType = BT_EVENT_SYNC_CONNECTION_UPDATED;
1593 vos_mem_copy( &btEvent.uEventParam.btSyncConnection,
1594 &pReplay->btcEventHist.btSyncUpdateEvent[i].btSyncConnection,
1595 sizeof(tSmeBtSyncConnectionParam) );
1596 btcSendBTEvent( pMac, &btEvent );
1597 }
1598 }
1599 //Clear all events
1600 vos_mem_zero( &pReplay->btcEventHist, sizeof(tSmeBtcEventHist) );
1601 }
1602}
1603
1604static void btcPowerStateCB( v_PVOID_t pContext, tPmcState pmcState )
1605{
1606 tpAniSirGlobal pMac = PMAC_STRUCT(pContext);
1607 if( FULL_POWER == pmcState )
1608 {
1609 btcReplayEvents( pMac );
1610 }
1611}
1612
1613/* ---------------------------------------------------------------------------
1614 \fn btcLogEvent
1615 \brief API to log the the current Bluetooth event
1616 \param hHal - The handle returned by macOpen.
1617 \param pSmeBtcConfig - Pointer to a caller allocated object of type
1618 tSmeBtEvent. Caller owns the memory and is responsible
1619 for freeing it.
1620 \return None
1621 ---------------------------------------------------------------------------*/
1622static void btcLogEvent (tHalHandle hHal, tpSmeBtEvent pBtEvent)
1623{
1624 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "%s: "
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001625 "Bluetooth Event %d received", __func__, pBtEvent->btEventType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001626 switch(pBtEvent->btEventType)
1627 {
1628 case BT_EVENT_CREATE_SYNC_CONNECTION:
1629 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
1630 case BT_EVENT_SYNC_CONNECTION_UPDATED:
1631 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "SCO Connection: "
1632 "connectionHandle = %d status = %d linkType %d "
1633 "scoInterval %d scoWindow %d retransmisisonWindow = %d ",
1634 pBtEvent->uEventParam.btSyncConnection.connectionHandle,
1635 pBtEvent->uEventParam.btSyncConnection.status,
1636 pBtEvent->uEventParam.btSyncConnection.linkType,
1637 pBtEvent->uEventParam.btSyncConnection.scoInterval,
1638 pBtEvent->uEventParam.btSyncConnection.scoWindow,
1639 pBtEvent->uEventParam.btSyncConnection.retransmisisonWindow);
1640 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BD ADDR = "
1641 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
1642 pBtEvent->uEventParam.btSyncConnection.bdAddr[5],
1643 pBtEvent->uEventParam.btSyncConnection.bdAddr[4],
1644 pBtEvent->uEventParam.btSyncConnection.bdAddr[3],
1645 pBtEvent->uEventParam.btSyncConnection.bdAddr[2],
1646 pBtEvent->uEventParam.btSyncConnection.bdAddr[1],
1647 pBtEvent->uEventParam.btSyncConnection.bdAddr[0]);
1648 break;
1649 case BT_EVENT_CREATE_ACL_CONNECTION:
1650 case BT_EVENT_ACL_CONNECTION_COMPLETE:
1651 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "ACL Connection: "
1652 "connectionHandle = %d status = %d ",
1653 pBtEvent->uEventParam.btAclConnection.connectionHandle,
1654 pBtEvent->uEventParam.btAclConnection.status);
1655 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "BD ADDR = "
1656 "0x%x 0x%x 0x%x 0x%x 0x%x 0x%x",
1657 pBtEvent->uEventParam.btAclConnection.bdAddr[5],
1658 pBtEvent->uEventParam.btAclConnection.bdAddr[4],
1659 pBtEvent->uEventParam.btAclConnection.bdAddr[3],
1660 pBtEvent->uEventParam.btAclConnection.bdAddr[2],
1661 pBtEvent->uEventParam.btAclConnection.bdAddr[1],
1662 pBtEvent->uEventParam.btAclConnection.bdAddr[0]);
1663 break;
1664 case BT_EVENT_MODE_CHANGED:
1665 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "ACL Mode change : "
1666 "connectionHandle %d mode %d ",
1667 pBtEvent->uEventParam.btAclModeChange.connectionHandle,
1668 pBtEvent->uEventParam.btAclModeChange.mode);
1669 break;
1670 case BT_EVENT_DISCONNECTION_COMPLETE:
1671 VOS_TRACE(VOS_MODULE_ID_SME, VOS_TRACE_LEVEL_ERROR, "Disconnect Event : "
1672 "connectionHandle %d ", pBtEvent->uEventParam.btAclModeChange.connectionHandle);
1673 break;
1674 default:
1675 break;
1676 }
1677 }
1678
1679/*
1680 Caller can check whether BTC's current event allows UAPSD. This doesn't affect
1681 BMPS.
1682 return: VOS_TRUE -- BTC is ready for UAPSD
1683 VOS_FALSE -- certain BT event is active, cannot enter UAPSD
1684*/
1685v_BOOL_t btcIsReadyForUapsd( tHalHandle hHal )
1686{
1687 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1688 return( pMac->btc.btcUapsdOk );
1689}
1690
1691/*
1692 Base on the BT event, this function sets the flag on whether to allow UAPSD
1693 At this time, we are only interested in SCO and A2DP.
1694 A2DP tracking is through BT_EVENT_A2DP_STREAM_START and BT_EVENT_A2DP_STREAM_STOP
1695 SCO is through BT_EVENT_SYNC_CONNECTION_COMPLETE and BT_EVENT_DISCONNECTION_COMPLETE
1696 BT_EVENT_DEVICE_SWITCHED_OFF overwrites them all
1697*/
1698void btcUapsdCheck( tpAniSirGlobal pMac, tpSmeBtEvent pBtEvent )
1699{
1700 v_U8_t i;
1701 v_BOOL_t fLastUapsdState = pMac->btc.btcUapsdOk, fMoreSCO = VOS_FALSE;
1702 switch( pBtEvent->btEventType )
1703 {
1704 case BT_EVENT_DISCONNECTION_COMPLETE:
1705 if( (VOS_FALSE == pMac->btc.btcUapsdOk) &&
1706 BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btDisconnect.connectionHandle )
1707 {
1708 //Check whether all SCO connections are gone
1709 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
1710 {
1711 if( (BT_INVALID_CONN_HANDLE != pMac->btc.btcScoHandles[i]) &&
1712 (pMac->btc.btcScoHandles[i] != pBtEvent->uEventParam.btDisconnect.connectionHandle) )
1713 {
1714 //We still have outstanding SCO connection
1715 fMoreSCO = VOS_TRUE;
1716 }
1717 else if( pMac->btc.btcScoHandles[i] == pBtEvent->uEventParam.btDisconnect.connectionHandle )
1718 {
1719 pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE;
1720 }
1721 }
1722 if( !fMoreSCO && !pMac->btc.fA2DPUp )
1723 {
1724 //All SCO is disconnected
1725 pMac->btc.btcUapsdOk = VOS_TRUE;
1726 smsLog( pMac, LOGE, "BT event (DISCONNECTION) happens, UAPSD-allowed flag (%d) change to TRUE \n",
1727 pBtEvent->btEventType, pMac->btc.btcUapsdOk );
1728 }
1729 }
1730 break;
1731 case BT_EVENT_DEVICE_SWITCHED_OFF:
1732 smsLog( pMac, LOGE, "BT event (DEVICE_OFF) happens, UAPSD-allowed flag (%d) change to TRUE \n",
1733 pBtEvent->btEventType, pMac->btc.btcUapsdOk );
1734 //Clean up SCO
1735 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
1736 {
1737 pMac->btc.btcScoHandles[i] = BT_INVALID_CONN_HANDLE;
1738 }
1739 pMac->btc.fA2DPUp = VOS_FALSE;
1740 pMac->btc.btcUapsdOk = VOS_TRUE;
1741 break;
1742 case BT_EVENT_A2DP_STREAM_STOP:
1743 smsLog( pMac, LOGE, "BT event (A2DP_STREAM_STOP) happens, UAPSD-allowed flag (%d) \n",
1744 pMac->btc.btcUapsdOk );
1745 pMac->btc.fA2DPUp = VOS_FALSE;
1746 //Check whether SCO is on
1747 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
1748 {
1749 if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE)
1750 {
1751 break;
1752 }
1753 }
1754 if( BT_MAX_SCO_SUPPORT == i )
1755 {
1756 pMac->btc.fA2DPTrafStop = VOS_TRUE;
1757 smsLog( pMac, LOGE, "BT_EVENT_A2DP_STREAM_STOP: UAPSD-allowed flag is now %d\n",
1758 pMac->btc.btcUapsdOk );
1759 }
1760 break;
1761
1762 case BT_EVENT_MODE_CHANGED:
1763 smsLog( pMac, LOGE, "BT event (BT_EVENT_MODE_CHANGED) happens, Mode (%d) UAPSD-allowed flag (%d)\n",
1764 pBtEvent->uEventParam.btAclModeChange.mode, pMac->btc.btcUapsdOk );
1765 if(pBtEvent->uEventParam.btAclModeChange.mode == BT_ACL_SNIFF)
1766 {
1767 //Check whether SCO is on
1768 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
1769 {
1770 if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE)
1771 {
1772 break;
1773 }
1774 }
1775 if( BT_MAX_SCO_SUPPORT == i )
1776 {
1777 if(VOS_TRUE == pMac->btc.fA2DPTrafStop)
1778 {
1779 pMac->btc.btcUapsdOk = VOS_TRUE;
1780 pMac->btc.fA2DPTrafStop = VOS_FALSE;
1781 }
1782 smsLog( pMac, LOGE, "BT_EVENT_MODE_CHANGED with Mode:%d UAPSD-allowed flag is now %d\n",
1783 pBtEvent->uEventParam.btAclModeChange.mode,pMac->btc.btcUapsdOk );
1784 }
1785 }
1786 break;
1787 case BT_EVENT_CREATE_SYNC_CONNECTION:
1788 {
1789 pMac->btc.btcUapsdOk = VOS_FALSE;
1790 smsLog( pMac, LOGE, "BT_EVENT_CREATE_SYNC_CONNECTION (%d) happens, UAPSD-allowed flag (%d) change to FALSE \n",
1791 pBtEvent->btEventType, pMac->btc.btcUapsdOk );
1792 }
1793 break;
1794 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
1795 //Make sure it is a success
1796 if( BT_CONN_STATUS_FAIL != pBtEvent->uEventParam.btSyncConnection.status )
1797 {
1798 //Save te handle for later use
1799 for( i = 0; i < BT_MAX_SCO_SUPPORT; i++)
1800 {
1801 VOS_ASSERT(BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btSyncConnection.connectionHandle);
1802 if( (BT_INVALID_CONN_HANDLE == pMac->btc.btcScoHandles[i]) &&
1803 (BT_INVALID_CONN_HANDLE != pBtEvent->uEventParam.btSyncConnection.connectionHandle))
1804 {
1805 pMac->btc.btcScoHandles[i] = pBtEvent->uEventParam.btSyncConnection.connectionHandle;
1806 break;
1807 }
1808 }
1809
1810 if( i >= BT_MAX_SCO_SUPPORT )
1811 {
1812 smsLog(pMac, LOGE, FL("Too many SCO, ignore this one\n"));
1813 }
1814 }
1815 else
1816 {
1817 //Check whether SCO is on
1818 for(i=0; i < BT_MAX_SCO_SUPPORT; i++)
1819 {
1820 if(pMac->btc.btcScoHandles[i] != BT_INVALID_CONN_HANDLE)
1821 {
1822 break;
1823 }
1824 }
1825 /*If No Other Sco/A2DP is ON reenable UAPSD*/
1826 if( (BT_MAX_SCO_SUPPORT == i) && !pMac->btc.fA2DPUp)
1827 {
1828 pMac->btc.btcUapsdOk = VOS_TRUE;
1829 }
1830 smsLog(pMac, LOGE, FL("TSYNC complete failed\n"));
1831 }
1832 break;
1833 case BT_EVENT_A2DP_STREAM_START:
1834 smsLog( pMac, LOGE, "BT_EVENT_A2DP_STREAM_START (%d) happens, UAPSD-allowed flag (%d) change to FALSE \n",
1835 pBtEvent->btEventType, pMac->btc.btcUapsdOk );
1836 pMac->btc.fA2DPTrafStop = VOS_FALSE;
1837 pMac->btc.btcUapsdOk = VOS_FALSE;
1838 pMac->btc.fA2DPUp = VOS_TRUE;
1839 break;
1840 default:
1841 //No change for these events
1842 smsLog( pMac, LOGE, "BT event (%d) happens, UAPSD-allowed flag (%d) no change \n",
1843 pBtEvent->btEventType, pMac->btc.btcUapsdOk );
1844 break;
1845 }
1846 if(fLastUapsdState != pMac->btc.btcUapsdOk)
1847 {
1848 sme_QosTriggerUapsdChange( pMac );
1849 }
1850}
1851
1852/* ---------------------------------------------------------------------------
1853 \fn btcHandleCoexInd
1854 \brief API to handle Coex indication from WDI
1855 \param pMac - The handle returned by macOpen.
1856 \return eHalStatus
1857 eHAL_STATUS_FAILURE success
1858 eHAL_STATUS_SUCCESS failure
1859 ---------------------------------------------------------------------------*/
1860eHalStatus btcHandleCoexInd(tHalHandle hHal, void* pMsg)
1861{
1862 tpAniSirGlobal pMac = PMAC_STRUCT( hHal );
1863 eHalStatus status = eHAL_STATUS_SUCCESS;
1864 tSirSmeCoexInd *pSmeCoexInd = (tSirSmeCoexInd *)pMsg;
1865
1866 if (NULL == pMsg)
1867 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001868 smsLog(pMac, LOGE, "in %s msg ptr is NULL\n", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001869 status = eHAL_STATUS_FAILURE;
1870 }
1871 else
1872 {
1873 // DEBUG
1874 smsLog(pMac, LOG1, "Coex indication in %s(), type %d",
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001875 __func__, pSmeCoexInd->coexIndType);
Jeff Johnson295189b2012-06-20 16:38:30 -07001876
1877 // suspend heartbeat monitoring
1878 if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_DISABLE_HB_MONITOR)
1879 {
1880 // set heartbeat threshold CFG to zero
1881 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, 0, NULL, eANI_BOOLEAN_FALSE);
1882 pMac->btc.btcHBActive = VOS_FALSE;
1883 }
1884
1885 // resume heartbeat monitoring
1886 else if (pSmeCoexInd->coexIndType == SIR_COEX_IND_TYPE_ENABLE_HB_MONITOR)
1887 {
1888 if (!pMac->btc.btcHBActive)
1889 {
1890 ccmCfgSetInt(pMac, WNI_CFG_HEART_BEAT_THRESHOLD, pMac->btc.btcHBCount, NULL, eANI_BOOLEAN_FALSE);
1891 pMac->btc.btcHBActive = VOS_TRUE;
1892 }
1893 }
1894
1895 // unknown indication type
1896 else
1897 {
Madan Mohan Koyyalamudi87054ba2012-11-02 13:24:12 -07001898 smsLog(pMac, LOGE, "unknown Coex indication type in %s()", __func__);
Jeff Johnson295189b2012-06-20 16:38:30 -07001899 }
1900 }
1901
1902 return(status);
1903}
1904
1905#ifdef FEATURE_WLAN_DIAG_SUPPORT
1906/* ---------------------------------------------------------------------------
1907 \fn btcDiagEventLog
1908 \brief API to log the the current Bluetooth event
1909 \param hHal - The handle returned by macOpen.
1910 \param pSmeBtcConfig - Pointer to a caller allocated object of type
1911 tSmeBtEvent. Caller owns the memory and is responsible
1912 for freeing it.
1913 \return None
1914 ---------------------------------------------------------------------------*/
1915static void btcDiagEventLog (tHalHandle hHal, tpSmeBtEvent pBtEvent)
1916{
1917 //vos_event_wlan_btc_type *log_ptr = NULL;
1918 WLAN_VOS_DIAG_EVENT_DEF(btDiagEvent, vos_event_wlan_btc_type);
1919 {
1920 btDiagEvent.eventId = pBtEvent->btEventType;
1921 switch(pBtEvent->btEventType)
1922 {
1923 case BT_EVENT_CREATE_SYNC_CONNECTION:
1924 case BT_EVENT_SYNC_CONNECTION_COMPLETE:
1925 case BT_EVENT_SYNC_CONNECTION_UPDATED:
1926 btDiagEvent.connHandle = pBtEvent->uEventParam.btSyncConnection.connectionHandle;
1927 btDiagEvent.connStatus = pBtEvent->uEventParam.btSyncConnection.status;
1928 btDiagEvent.linkType = pBtEvent->uEventParam.btSyncConnection.linkType;
1929 btDiagEvent.scoInterval = pBtEvent->uEventParam.btSyncConnection.scoInterval;
1930 btDiagEvent.scoWindow = pBtEvent->uEventParam.btSyncConnection.scoWindow;
1931 btDiagEvent.retransWindow = pBtEvent->uEventParam.btSyncConnection.retransmisisonWindow;
1932 vos_mem_copy(btDiagEvent.btAddr, pBtEvent->uEventParam.btSyncConnection.bdAddr,
1933 sizeof(btDiagEvent.btAddr));
1934 break;
1935 case BT_EVENT_CREATE_ACL_CONNECTION:
1936 case BT_EVENT_ACL_CONNECTION_COMPLETE:
1937 btDiagEvent.connHandle = pBtEvent->uEventParam.btAclConnection.connectionHandle;
1938 btDiagEvent.connStatus = pBtEvent->uEventParam.btAclConnection.status;
1939 vos_mem_copy(btDiagEvent.btAddr, pBtEvent->uEventParam.btAclConnection.bdAddr,
1940 sizeof(btDiagEvent.btAddr));
1941 break;
1942 case BT_EVENT_MODE_CHANGED:
1943 btDiagEvent.connHandle = pBtEvent->uEventParam.btAclModeChange.connectionHandle;
1944 btDiagEvent.mode = pBtEvent->uEventParam.btAclModeChange.mode;
1945 break;
1946 case BT_EVENT_DISCONNECTION_COMPLETE:
1947 btDiagEvent.connHandle = pBtEvent->uEventParam.btAclModeChange.connectionHandle;
1948 break;
1949 default:
1950 break;
1951 }
1952 }
1953 WLAN_VOS_DIAG_EVENT_REPORT(&btDiagEvent, EVENT_WLAN_BTC);
1954}
1955#endif /* FEATURE_WLAN_DIAG_SUPPORT */
1956#endif /* WLAN_MDM_CODE_REDUCTION_OPT*/