wlan: check if tdls exists when tdls peer timer expires.
when wlan_hdd_tdls_initiator_wait_cb gets called, the tdls peer
might not exists as there is a chance that the peer may get deleted
as part of disconnection.
So check if tdls exists before accessing the peer in
wlan_hdd_tdls_initiator_wait_cb.
Change-Id: I90a7a765997bf3641bf2c8de2f3c9e5068e89122
CRs-Fixed: 906303
diff --git a/CORE/HDD/inc/wlan_hdd_main.h b/CORE/HDD/inc/wlan_hdd_main.h
index b928904..823e11c 100644
--- a/CORE/HDD/inc/wlan_hdd_main.h
+++ b/CORE/HDD/inc/wlan_hdd_main.h
@@ -1569,6 +1569,8 @@
void hdd_dump_concurrency_info(hdd_context_t *pHddCtx);
hdd_adapter_t * hdd_get_adapter_by_name( hdd_context_t *pHddCtx, tANI_U8 *name );
hdd_adapter_t * hdd_get_adapter_by_macaddr( hdd_context_t *pHddCtx, tSirMacAddr macAddr );
+hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
+ tANI_U32 sme_session_id );
hdd_adapter_t * hdd_get_mon_adapter( hdd_context_t *pHddCtx );
VOS_STATUS hdd_init_station_mode( hdd_adapter_t *pAdapter );
hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode );
diff --git a/CORE/HDD/inc/wlan_hdd_tdls.h b/CORE/HDD/inc/wlan_hdd_tdls.h
index 03d91f9..b004f6c 100644
--- a/CORE/HDD/inc/wlan_hdd_tdls.h
+++ b/CORE/HDD/inc/wlan_hdd_tdls.h
@@ -486,4 +486,11 @@
#endif
void wlan_hdd_tdls_update_rx_pkt_cnt_n_rssi(hdd_adapter_t *pAdapter,
u8 *mac, v_S7_t rssiAvg);
+
+
+tdlsConnInfo_t *wlan_hdd_get_conn_info(hdd_context_t *pHddCtx,
+ tANI_U8 idx);
+
+v_VOID_t wlan_hdd_tdls_initiator_wait_cb(v_PVOID_t userData);
+
#endif // __HDD_TDSL_H
diff --git a/CORE/HDD/src/wlan_hdd_cfg80211.c b/CORE/HDD/src/wlan_hdd_cfg80211.c
index 12ed8ab..34d39f1 100644
--- a/CORE/HDD/src/wlan_hdd_cfg80211.c
+++ b/CORE/HDD/src/wlan_hdd_cfg80211.c
@@ -16420,6 +16420,16 @@
if (pTdlsPeer->is_responder == 0)
{
v_U8_t staId = (v_U8_t)pTdlsPeer->staId;
+ tdlsConnInfo_t *tdlsInfo;
+
+ tdlsInfo = wlan_hdd_get_conn_info(pHddCtx, staId);
+
+ /* Initialize initiator wait callback */
+ vos_timer_init(
+ &pTdlsPeer->initiatorWaitTimeoutTimer,
+ VOS_TIMER_TYPE_SW,
+ wlan_hdd_tdls_initiator_wait_cb,
+ tdlsInfo);
wlan_hdd_tdls_timer_restart(pAdapter,
&pTdlsPeer->initiatorWaitTimeoutTimer,
diff --git a/CORE/HDD/src/wlan_hdd_main.c b/CORE/HDD/src/wlan_hdd_main.c
index a0d6da2..cee77a3 100755
--- a/CORE/HDD/src/wlan_hdd_main.c
+++ b/CORE/HDD/src/wlan_hdd_main.c
@@ -8048,6 +8048,34 @@
}
+hdd_adapter_t *hdd_get_adapter_by_sme_session_id( hdd_context_t *pHddCtx,
+ tANI_U32 sme_session_id )
+{
+ hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
+ hdd_adapter_t *pAdapter;
+ VOS_STATUS vos_status;
+
+
+ vos_status = hdd_get_front_adapter( pHddCtx, &pAdapterNode);
+
+ while ((NULL != pAdapterNode) && (VOS_STATUS_SUCCESS == vos_status))
+ {
+ pAdapter = pAdapterNode->pAdapter;
+
+ if (pAdapter->sessionId == sme_session_id)
+ return pAdapter;
+
+ vos_status = hdd_get_next_adapter(pHddCtx, pAdapterNode, &pNext);
+ pAdapterNode = pNext;
+ }
+
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ "%s: sme_session_id %d does not exist with host",
+ __func__, sme_session_id);
+
+ return NULL;
+}
+
hdd_adapter_t * hdd_get_adapter( hdd_context_t *pHddCtx, device_mode_t mode )
{
hdd_adapter_list_node_t *pAdapterNode = NULL, *pNext = NULL;
diff --git a/CORE/HDD/src/wlan_hdd_tdls.c b/CORE/HDD/src/wlan_hdd_tdls.c
index 3d69137..eea0994 100644
--- a/CORE/HDD/src/wlan_hdd_tdls.c
+++ b/CORE/HDD/src/wlan_hdd_tdls.c
@@ -682,19 +682,57 @@
return;
}
-static v_VOID_t wlan_hdd_tdls_initiator_wait_cb( v_PVOID_t userData )
+v_VOID_t wlan_hdd_tdls_initiator_wait_cb( v_PVOID_t userData )
{
- hddTdlsPeer_t *curr_peer = (hddTdlsPeer_t *)userData;
+ tdlsConnInfo_t *tdlsInfo = (tdlsConnInfo_t *) userData;
tdlsCtx_t *pHddTdlsCtx;
+ hdd_context_t *pHddCtx = NULL;
+ hdd_adapter_t *pAdapter = NULL;
+ v_CONTEXT_t pVosContext = vos_get_global_context(VOS_MODULE_ID_HDD, NULL);
+ hddTdlsPeer_t *curr_peer = NULL;
ENTER();
- if ( NULL == curr_peer )
+
+ if (!tdlsInfo->staId)
{
VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
- FL("curr_peer is NULL"));
+ FL("peer (staidx %u) doesn't exists"), tdlsInfo->staId);
+ return;
+ }
+ if (!pVosContext)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ FL("pVosContext is NULL"));
return;
}
+ pHddCtx = vos_get_context( VOS_MODULE_ID_HDD, pVosContext);
+ if (!pHddCtx)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ FL("pHddCtx is NULL"));
+ return;
+ }
+
+ pAdapter = hdd_get_adapter_by_sme_session_id(pHddCtx, tdlsInfo->sessionId);
+
+ if (!pAdapter)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ FL("pAdapter is NULL"));
+ return;
+ }
+
+ mutex_lock(&pHddCtx->tdls_lock);
+ curr_peer = wlan_hdd_tdls_find_peer(pAdapter,
+ (u8 *) &tdlsInfo->peerMac.bytes[0], FALSE);
+ if (curr_peer == NULL)
+ {
+ VOS_TRACE(VOS_MODULE_ID_HDD, VOS_TRACE_LEVEL_ERROR,
+ FL("peer doesn't exists"));
+ mutex_unlock(&pHddCtx->tdls_lock);
+ return;
+ }
pHddTdlsCtx = curr_peer->pHddTdlsCtx;
if ( NULL == pHddTdlsCtx )
@@ -710,6 +748,7 @@
}
WLANTL_ResumeDataTx( (WLAN_HDD_GET_CTX(pHddTdlsCtx->pAdapter))->pvosContext,
(v_U8_t *)&curr_peer->staId);
+ mutex_unlock(&pHddCtx->tdls_lock);
EXIT();
}
@@ -1107,7 +1146,8 @@
__func__,
MAC_ADDR_ARRAY(curr_peer->peerMac));
vos_timer_stop ( &curr_peer->peerIdleTimer );
- vos_timer_stop( &curr_peer->initiatorWaitTimeoutTimer );
+ if (vos_timer_is_initialized(&curr_peer->initiatorWaitTimeoutTimer))
+ vos_timer_stop( &curr_peer->initiatorWaitTimeoutTimer );
}
}
}
@@ -1150,8 +1190,11 @@
MAC_ADDR_ARRAY(curr_peer->peerMac));
vos_timer_stop ( &curr_peer->peerIdleTimer );
vos_timer_destroy ( &curr_peer->peerIdleTimer );
- vos_timer_stop(&curr_peer->initiatorWaitTimeoutTimer);
- vos_timer_destroy(&curr_peer->initiatorWaitTimeoutTimer);
+ if (vos_timer_is_initialized(&curr_peer->initiatorWaitTimeoutTimer))
+ {
+ vos_timer_stop(&curr_peer->initiatorWaitTimeoutTimer);
+ vos_timer_destroy(&curr_peer->initiatorWaitTimeoutTimer);
+ }
}
}
@@ -1229,12 +1272,6 @@
VOS_TIMER_TYPE_SW,
wlan_hdd_tdls_idle_cb,
peer);
-
- vos_timer_init(&peer->initiatorWaitTimeoutTimer,
- VOS_TIMER_TYPE_SW,
- wlan_hdd_tdls_initiator_wait_cb,
- peer);
-
list_add_tail(&peer->node, head);
return peer;
@@ -3310,4 +3347,22 @@
FALSE);
}
}
+
+tdlsConnInfo_t *wlan_hdd_get_conn_info(hdd_context_t *pHddCtx,
+ tANI_U8 idx)
+{
+ tANI_U8 staIdx;
+
+ /* check if there is available index for this new TDLS STA */
+ for ( staIdx = 0; staIdx < HDD_MAX_NUM_TDLS_STA; staIdx++ )
+ {
+ if (idx == pHddCtx->tdlsConnInfo[staIdx].staId )
+ {
+ hddLog(LOG1, FL("tdls peer with staIdx %u exists"), idx );
+ return (&pHddCtx->tdlsConnInfo[staIdx]);
+ }
+ }
+ hddLog(LOGE, FL("tdls peer with staIdx %u not exists"), idx );
+ return NULL;
+}
/*EXT TDLS*/
diff --git a/CORE/VOSS/inc/vos_timer.h b/CORE/VOSS/inc/vos_timer.h
index c056a7e..49414e1 100644
--- a/CORE/VOSS/inc/vos_timer.h
+++ b/CORE/VOSS/inc/vos_timer.h
@@ -328,6 +328,6 @@
------------------------------------------------------------------------*/
v_TIME_t vos_timer_get_system_time( v_VOID_t );
-
+v_BOOL_t vos_timer_is_initialized(vos_timer_t *timer);
#endif // #if !defined __VOSS_TIMER_H
diff --git a/CORE/VOSS/src/vos_timer.c b/CORE/VOSS/src/vos_timer.c
index f67ba33..27e7ca9 100644
--- a/CORE/VOSS/src/vos_timer.c
+++ b/CORE/VOSS/src/vos_timer.c
@@ -886,3 +886,24 @@
do_gettimeofday(&tv);
return tv.tv_sec*1000 + tv.tv_usec/1000;
}
+
+/*--------------------------------------------------------------------------
+
+ \brief vos_timer_is_initialized() - check if timer is initialized or not
+
+ The \a vos_timer_is_initialized() function returns VOS_TRUE if timer is
+ initialized and VOS_FALSE if timer is not initialized
+
+ \returns - VOS_TRUE or VOS_FALSE
+
+ \sa
+
+ ------------------------------------------------------------------------*/
+v_BOOL_t vos_timer_is_initialized(vos_timer_t *timer)
+{
+ if (LINUX_TIMER_COOKIE == timer->platformInfo.cookie)
+ return VOS_TRUE;
+ else
+ return VOS_FALSE;
+}
+