예제 #1
0
/*
========================================================================
Routine Description:
    MLME kernel thread.

Arguments:
	*Context			the pAd, driver control block pointer

Return Value:
    0					close the thread

Note:
========================================================================
*/
INT MlmeThread(
    IN ULONG Context)
{
    RTMP_ADAPTER *pAd;
    RTMP_OS_TASK *pTask;
    int status;
    status = 0;

    pTask = (RTMP_OS_TASK *)Context;
    pAd = (PRTMP_ADAPTER)pTask->priv;

    RtmpOSTaskCustomize(pTask);

    while(!pTask->task_killed)
    {
#ifdef KTHREAD_SUPPORT
        RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
#else
        RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);

        /* unlock the device pointers */
        if (status != 0)
        {
            RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
            break;
        }
#endif

        /* lock the device pointers , need to check if required*/
        //down(&(pAd->usbdev_semaphore));

        if (!pAd->PM_FlgSuspend)
            MlmeHandler(pAd);
    }

    /* notify the exit routine that we're actually exiting now
     *
     * complete()/wait_for_completion() is similar to up()/down(),
     * except that complete() is safe in the case where the structure
     * is getting deleted in a parallel mode of execution (i.e. just
     * after the down() -- that's necessary for the thread-shutdown
     * case.
     *
     * complete_and_exit() goes even further than this -- it is safe in
     * the case that the thread of the caller is going away (not just
     * the structure) -- this is necessary for the module-remove case.
     * This is important in preemption kernels, which transfer the flow
     * of execution immediately upon a complete().
     */
    DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
#ifndef KTHREAD_SUPPORT
    pTask->taskPID = THREAD_PID_INIT_VALUE;
    complete_and_exit (&pTask->taskComplete, 0);
#endif
    return 0;

}
예제 #2
0
/*
========================================================================
Routine Description:
    MLME kernel thread.

Arguments:
	*Context			the pAd, driver control block pointer

Return Value:
    0					close the thread

Note:
========================================================================
*/
INT MlmeThread(
	IN ULONG Context)
{
	RTMP_ADAPTER *pAd;
	RTMP_OS_TASK *pTask;
	int status;
	status = 0;

	pTask = (RTMP_OS_TASK *)Context;
	pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask);
	if (pAd == NULL)
		goto LabelExit; /* avoid compile warning */

	RtmpOSTaskCustomize(pTask);

	while(!RTMP_OS_TASK_IS_KILLED(pTask))
	{
		if (RtmpOSTaskWait(pAd, pTask, &status) == FALSE)
		{
			DBGPRINT_ERR(("RtmpOSTaskWait returned false in MlmeThread, setting halt in progress flag!\n"));
			RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
			break;
		}
			
		/* lock the device pointers , need to check if required*/
		/*down(&(pAd->usbdev_semaphore)); */
		
		if (!pAd->PM_FlgSuspend)
			MlmeHandler(pAd);
	}

	/* notify the exit routine that we're actually exiting now 
	 *
	 * complete()/wait_for_completion() is similar to up()/down(),
	 * except that complete() is safe in the case where the structure
	 * is getting deleted in a parallel mode of execution (i.e. just
	 * after the down() -- that's necessary for the thread-shutdown
	 * case.
	 *
	 * complete_and_exit() goes even further than this -- it is safe in
	 * the case that the thread of the caller is going away (not just
	 * the structure) -- this is necessary for the module-remove case.
	 * This is important in preemption kernels, which transfer the flow
	 * of execution immediately upon a complete().
	 */
LabelExit:
	DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
	RtmpOSTaskNotifyToExit(pTask);
	return 0;

}
예제 #3
0
INT MlmeThread(
    IN void * Context)
{
	PRTMP_ADAPTER	pAd = (PRTMP_ADAPTER)Context;
//2007/12/11:KH modified to fix compiled failed
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
	daemonize();
#else
	daemonize("rt73");
#endif
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
	allow_signal(SIGTERM);
#endif
	current->flags |= PF_NOFREEZE;
	/* signal that we've started the thread */
	complete(&(pAd->MlmeThreadNotify));

	while (1)
	{
		int status;
		
		status = down_interruptible(&pAd->mlme_semaphore);
		if (status != 0)
			continue;

		if (mlme_kill)
			break;

		MlmeHandler(pAd);

	}

	/* notify the exit routine that we're actually exiting now 
	 *
	 * complete()/wait_for_completion() is similar to up()/down(),
	 * except that complete() is safe in the case where the structure
	 * is getting deleted in a parallel mode of execution (i.e. just
	 * after the down() -- that's necessary for the thread-shutdown
	 * case.
	 *
	 * complete_and_exit() goes even further than this -- it is safe in
	 * the case that the thread of the caller is going away (not just
	 * the structure) -- this is necessary for the module-remove case.
	 * This is important in preemption kernels, which transfer the flow
	 * of execution immediately upon a complete().
	 */
	complete_and_exit (&pAd->MlmeThreadNotify, 0);
	DBGPRINT(RT_DEBUG_TRACE, "<---MlmeThread\n");

}
예제 #4
0
파일: p2p_action.c 프로젝트: aircross/ray
VOID PeerP2pPresReqAction(
	IN PRTMP_ADAPTER pAd, 
	IN MLME_QUEUE_ELEM *Elem) 
{
	MLME_P2P_ACTION_STRUCT	P2PActReq;	
	MAC_TABLE_ENTRY		*pEntry;
	PFRAME_P2P_ACTION		pFrame;
	PP2P_NOA_DESC	pNoADesc;	
	
	pFrame = (PFRAME_P2P_ACTION)Elem->Msg;

	if (Elem->Wcid >= MAX_LEN_OF_MAC_TABLE)
	{
		DBGPRINT(RT_DEBUG_ERROR, ("PeerP2pPresReqAction. unknown Elem->Wcid  = %d \n", Elem->Wcid ));
	}
		
	DBGPRINT(RT_DEBUG_ERROR, ("PeerP2pPresReqAction. Send back to Elem->Wcid  = %d \n", Elem->Wcid ));
		
	pEntry = &pAd->MacTab.Content[Elem->Wcid];

	pNoADesc = (PP2P_NOA_DESC)(&Elem->Msg[11 + sizeof(FRAME_P2P_ACTION)]);
	pEntry->P2pInfo.NoADesc[0].Count = pNoADesc->Count;
	pEntry->P2pInfo.NoADesc[0].Duration = *(PULONG)&pNoADesc->Duration[0];
	pEntry->P2pInfo.NoADesc[0].Interval = *(PULONG)&pNoADesc->Interval[0];
	pEntry->P2pInfo.NoADesc[0].StartTime = *(PULONG)&pNoADesc->StartTime[0];
	DBGPRINT(RT_DEBUG_ERROR,(" pP2pEntry->NoADesc[0].Count = %d, \n", pEntry->P2pInfo.NoADesc[0].Count));
	DBGPRINT(RT_DEBUG_ERROR,(" pP2pEntry->NoADesc[0].Duration = %d, \n", pEntry->P2pInfo.NoADesc[0].Duration));
	DBGPRINT(RT_DEBUG_ERROR,(" pP2pEntry->NoADesc[0].Interval = %d, \n", pEntry->P2pInfo.NoADesc[0].Interval));
	DBGPRINT(RT_DEBUG_ERROR,(" pP2pEntry->NoADesc[0].StartTime = %d, \n", pEntry->P2pInfo.NoADesc[0].StartTime));
	DBGPRINT(RT_DEBUG_ERROR,("pFrame->Token  = %d \n", pFrame->Token));

	pEntry->P2pInfo.NoAToken = pFrame->Token;
/*	pP2pEntry->NoADesc[0].Duration = Elem->Msg; */
	NdisZeroMemory(&P2PActReq, sizeof(P2PActReq));
	COPY_MAC_ADDR(P2PActReq.Addr, pEntry->Addr);
	P2PActReq.TabIndex = Elem->Wcid;
	MlmeEnqueue(pAd, P2P_ACTION_STATE_MACHINE, MT2_MLME_P2P_PRESENCE_RSP, sizeof(MLME_P2P_ACTION_STRUCT), (PVOID)&P2PActReq, 0);
	MlmeHandler(pAd);

}
예제 #5
0
/* 
    ==========================================================================
    Description:
        When waiting joining the (I)BSS, beacon received from external
    ==========================================================================
 */
static VOID ApCliPeerProbeRspAtJoinAction(
	IN PRTMP_ADAPTER pAd, 
	IN MLME_QUEUE_ELEM *Elem) 
{
	USHORT LenVIE;
	UCHAR *VarIE = NULL;
	NDIS_802_11_VARIABLE_IEs *pVIE = NULL;
	APCLI_CTRL_MSG_STRUCT ApCliCtrlMsg;
	PAPCLI_STRUCT pApCliEntry = NULL;
#ifdef DOT11_N_SUPPORT
	UCHAR CentralChannel;
#endif /* DOT11_N_SUPPORT */
	USHORT ifIndex = (USHORT)(Elem->Priv);
	PULONG pCurrState = NULL;
	BCN_IE_LIST *ie_list = NULL;

	if (ifIndex >= MAX_APCLI_NUM)
		return;

	pCurrState = &pAd->ApCfg.ApCliTab[ifIndex].SyncCurrState;

	/* Init Variable IE structure */
	os_alloc_mem(NULL, (UCHAR **)&VarIE, MAX_VIE_LEN);
	if (VarIE == NULL)
	{
		DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__));
		goto LabelErr;
	}
	pVIE = (PNDIS_802_11_VARIABLE_IEs) VarIE;
	pVIE->Length = 0;
	
	os_alloc_mem(NULL, (UCHAR **)&ie_list, sizeof(BCN_IE_LIST));
	if (ie_list == NULL)
	{
		DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate ie_list fail!!!\n", __FUNCTION__));
		goto LabelErr;
	}
	NdisZeroMemory(ie_list, sizeof(BCN_IE_LIST));




	if (PeerBeaconAndProbeRspSanity(pAd, 
								Elem->Msg, 
								Elem->MsgLen, 
								Elem->Channel,
								ie_list,
								&LenVIE,
								pVIE))
	{
		/*
			BEACON from desired BSS/IBSS found. We should be able to decide most
			BSS parameters here.
			Q. But what happen if this JOIN doesn't conclude a successful ASSOCIATEION?
				Do we need to receover back all parameters belonging to previous BSS?
			A. Should be not. There's no back-door recover to previous AP. It still need
				a new JOIN-AUTH-ASSOC sequence.
		*/
		INT ssidEqualFlag = FALSE;
		INT ssidEmptyFlag = FALSE;
		INT bssidEqualFlag = FALSE;
		INT bssidEmptyFlag = FALSE;
		INT matchFlag = FALSE;

		pApCliEntry = &pAd->ApCfg.ApCliTab[ifIndex];

		/* Check the Probe-Rsp's Bssid. */
		if(!MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ZERO_MAC_ADDR))
			bssidEqualFlag = MAC_ADDR_EQUAL(pApCliEntry->CfgApCliBssid, ie_list->Bssid);
		else
			bssidEmptyFlag = TRUE;

		/* Check the Probe-Rsp's Ssid. */
		if(pApCliEntry->CfgSsidLen != 0)
			ssidEqualFlag = SSID_EQUAL(pApCliEntry->CfgSsid, pApCliEntry->CfgSsidLen, ie_list->Ssid, ie_list->SsidLen);
		else
			ssidEmptyFlag = TRUE;


		/* bssid and ssid, Both match. */
		if (bssidEqualFlag && ssidEqualFlag)
			matchFlag = TRUE;

		/* ssid match but bssid doesn't be indicate. */
		else if(ssidEqualFlag && bssidEmptyFlag)
			matchFlag = TRUE;

		/* user doesn't indicate any bssid or ssid. AP-Clinet will auto pick a AP to join by most strong siganl strength. */
		else if (bssidEmptyFlag && ssidEmptyFlag)
			matchFlag = TRUE;


		DBGPRINT(RT_DEBUG_TRACE, ("SYNC - bssidEqualFlag=%d, ssidEqualFlag=%d, matchFlag=%d\n", bssidEqualFlag, ssidEqualFlag, matchFlag));
		if (matchFlag)
		{
			/* Validate RSN IE if necessary, then copy store this information */
			if ((LenVIE > 0) 
#ifdef WSC_AP_SUPPORT
                && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || 
                	(pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE))
#endif /* WSC_AP_SUPPORT */
                )
			{
				if (ApCliValidateRSNIE(pAd, (PEID_STRUCT)pVIE, LenVIE, ifIndex))
				{
					pApCliEntry->ApCliMlmeAux.VarIELen = LenVIE;
					NdisMoveMemory(pApCliEntry->ApCliMlmeAux.VarIEs, pVIE, pApCliEntry->ApCliMlmeAux.VarIELen);
				}
				else
				{
					/* ignore this response */
					pApCliEntry->ApCliMlmeAux.VarIELen = 0;
					DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The RSN IE of this received Probe-resp is dis-match !!!!!!!!!! \n"));
					goto LabelErr;
				}
			}
			else
			{
				if (pApCliEntry->AuthMode >= Ndis802_11AuthModeWPA
#ifdef WSC_AP_SUPPORT
                    && ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode == WSC_DISABLE) || 
                		(pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == FALSE))
#endif /* WSC_AP_SUPPORT */
                    )
				{
					/* ignore this response */
					DBGPRINT(RT_DEBUG_ERROR, ("ERROR: The received Probe-resp has empty RSN IE !!!!!!!!!! \n"));
					goto LabelErr;
				}	
				
				pApCliEntry->ApCliMlmeAux.VarIELen = 0;
			}

			DBGPRINT(RT_DEBUG_TRACE, ("SYNC - receive desired PROBE_RSP at JoinWaitProbeRsp... Channel = %d\n", ie_list->Channel));

			/* if the Bssid doesn't be indicated then you need to decide which AP to connect by most strong Rssi signal strength. */
			if (bssidEqualFlag == FALSE)
			{
				/* caculate real rssi value. */
				CHAR Rssi0 = ConvertToRssi(pAd, Elem->Rssi0, RSSI_0);
				CHAR Rssi1 = ConvertToRssi(pAd, Elem->Rssi1, RSSI_1);
				CHAR Rssi2 = ConvertToRssi(pAd, Elem->Rssi2, RSSI_2);
				LONG RealRssi = (LONG)(RTMPMaxRssi(pAd, Rssi0, Rssi1, Rssi2));

				DBGPRINT(RT_DEBUG_TRACE, ("SYNC - previous Rssi = %ld current Rssi=%ld\n", pApCliEntry->ApCliMlmeAux.Rssi, (LONG)RealRssi));
				if (pApCliEntry->ApCliMlmeAux.Rssi > (LONG)RealRssi)
					goto LabelErr;
				else
					pApCliEntry->ApCliMlmeAux.Rssi = RealRssi;
			} else
			{
				BOOLEAN Cancelled;
				RTMPCancelTimer(&pApCliEntry->ApCliMlmeAux.ProbeTimer, &Cancelled);
			}

			NdisMoveMemory(pApCliEntry->ApCliMlmeAux.Ssid, ie_list->Ssid, ie_list->SsidLen);
			pApCliEntry->ApCliMlmeAux.SsidLen = ie_list->SsidLen;

			NdisMoveMemory(pApCliEntry->ApCliMlmeAux.Bssid, ie_list->Bssid, MAC_ADDR_LEN);			
			pApCliEntry->ApCliMlmeAux.CapabilityInfo = ie_list->CapabilityInfo & SUPPORTED_CAPABILITY_INFO;
			pApCliEntry->ApCliMlmeAux.BssType = ie_list->BssType;
			pApCliEntry->ApCliMlmeAux.BeaconPeriod = ie_list->BeaconPeriod;
			pApCliEntry->ApCliMlmeAux.Channel = ie_list->Channel;
			pApCliEntry->ApCliMlmeAux.AtimWin = ie_list->AtimWin;
			pApCliEntry->ApCliMlmeAux.CfpPeriod = ie_list->CfParm.CfpPeriod;
			pApCliEntry->ApCliMlmeAux.CfpMaxDuration = ie_list->CfParm.CfpMaxDuration;
			pApCliEntry->ApCliMlmeAux.APRalinkIe = ie_list->RalinkIe;

			/* Copy AP's supported rate to ApCliMlmeAux for creating assoication request */
			/* Also filter out not supported rate */
			pApCliEntry->ApCliMlmeAux.SupRateLen = ie_list->SupRateLen;
			NdisMoveMemory(pApCliEntry->ApCliMlmeAux.SupRate, ie_list->SupRate, ie_list->SupRateLen);
			RTMPCheckRates(pAd, pApCliEntry->ApCliMlmeAux.SupRate, &pApCliEntry->ApCliMlmeAux.SupRateLen);
			pApCliEntry->ApCliMlmeAux.ExtRateLen = ie_list->ExtRateLen;
			NdisMoveMemory(pApCliEntry->ApCliMlmeAux.ExtRate, ie_list->ExtRate, ie_list->ExtRateLen);
			RTMPCheckRates(pAd, pApCliEntry->ApCliMlmeAux.ExtRate, &pApCliEntry->ApCliMlmeAux.ExtRateLen);

#ifdef DOT11_N_SUPPORT
			NdisZeroMemory(pApCliEntry->RxMcsSet,sizeof(pApCliEntry->RxMcsSet));
			/* filter out un-supported ht rates */
			if ((ie_list->HtCapabilityLen > 0) && 
				(pApCliEntry->DesiredHtPhyInfo.bHtEnable) &&
				WMODE_CAP_N(pAd->CommonCfg.PhyMode))
			{
				RTMPZeroMemory(&pApCliEntry->ApCliMlmeAux.HtCapability, SIZE_HT_CAP_IE);
				pApCliEntry->ApCliMlmeAux.NewExtChannelOffset = ie_list->NewExtChannelOffset;
				pApCliEntry->ApCliMlmeAux.HtCapabilityLen = ie_list->HtCapabilityLen;
				ApCliCheckHt(pAd, ifIndex, &ie_list->HtCapability, &ie_list->AddHtInfo);

				if (ie_list->AddHtInfoLen > 0)
				{
					CentralChannel = ie_list->AddHtInfo.ControlChan;
		 			/* Check again the Bandwidth capability of this AP. */
					CentralChannel = get_cent_ch_by_htinfo(pAd, &ie_list->AddHtInfo,
														&ie_list->HtCapability);
		 			DBGPRINT(RT_DEBUG_TRACE, ("PeerBeaconAtJoinAction HT===>Central Channel = %d, Control Channel = %d,  .\n", CentralChannel, ie_list->AddHtInfo.ControlChan));

				}
				
			}
			else
#endif /* DOT11_N_SUPPORT */
			{
				RTMPZeroMemory(&pApCliEntry->ApCliMlmeAux.HtCapability, SIZE_HT_CAP_IE);
				RTMPZeroMemory(&pApCliEntry->ApCliMlmeAux.AddHtInfo, SIZE_ADD_HT_INFO_IE);
				pApCliEntry->ApCliMlmeAux.HtCapabilityLen = 0;
			}
			ApCliUpdateMlmeRate(pAd, ifIndex);

#ifdef DOT11_N_SUPPORT
			/* copy QOS related information */
			if (WMODE_CAP_N(pAd->CommonCfg.PhyMode))
			{
				NdisMoveMemory(&pApCliEntry->ApCliMlmeAux.APEdcaParm, &ie_list->EdcaParm, sizeof(EDCA_PARM));
				NdisMoveMemory(&pApCliEntry->ApCliMlmeAux.APQbssLoad, &ie_list->QbssLoad, sizeof(QBSS_LOAD_PARM));
				NdisMoveMemory(&pApCliEntry->ApCliMlmeAux.APQosCapability, &ie_list->QosCapability, sizeof(QOS_CAPABILITY_PARM));
			}
			else
#endif /* DOT11_N_SUPPORT */
			{
				NdisZeroMemory(&pApCliEntry->ApCliMlmeAux.APEdcaParm, sizeof(EDCA_PARM));
				NdisZeroMemory(&pApCliEntry->ApCliMlmeAux.APQbssLoad, sizeof(QBSS_LOAD_PARM));
				NdisZeroMemory(&pApCliEntry->ApCliMlmeAux.APQosCapability, sizeof(QOS_CAPABILITY_PARM));
			}

			DBGPRINT(RT_DEBUG_TRACE, ("APCLI SYNC - after JOIN, SupRateLen=%d, ExtRateLen=%d\n", 
				pApCliEntry->ApCliMlmeAux.SupRateLen, pApCliEntry->ApCliMlmeAux.ExtRateLen));

			if (ie_list->AironetCellPowerLimit != 0xFF)
			{
				/*We need to change our TxPower for CCX 2.0 AP Control of Client Transmit Power */
				ChangeToCellPowerLimit(pAd, ie_list->AironetCellPowerLimit);
			}
			else  /*Used the default TX Power Percentage. */
				pAd->CommonCfg.TxPowerPercentage = pAd->CommonCfg.TxPowerDefault;

#ifdef WSC_AP_SUPPORT
#ifdef DOT11_N_SUPPORT
			if ((pAd->ApCfg.ApCliTab[ifIndex].WscControl.WscConfMode != WSC_DISABLE) &&
                (pAd->ApCfg.ApCliTab[ifIndex].WscControl.bWscTrigger == TRUE))
			{
				ADD_HTINFO	RootApHtInfo, ApHtInfo;
				ApHtInfo = pAd->CommonCfg.AddHTInfo.AddHtInfo;
				RootApHtInfo = ie_list->AddHtInfo.AddHtInfo;
				if ((pAd->CommonCfg.HtCapability.HtCapInfo.ChannelWidth  == BW_40) &&
					(RootApHtInfo.RecomWidth) &&
					(RootApHtInfo.ExtChanOffset != ApHtInfo.ExtChanOffset))
				{
					/*STRING	ChStr[5] = {0}; */
					
					if (RootApHtInfo.ExtChanOffset == EXTCHA_ABOVE)
						Set_HtExtcha_Proc(pAd, "1");
					else
						Set_HtExtcha_Proc(pAd, "0");

					goto LabelErr;
				}				
			}
#endif /* DOT11_N_SUPPORT */
#endif /* WSC_AP_SUPPORT */
			if(bssidEqualFlag == TRUE)
			{
				*pCurrState = APCLI_SYNC_IDLE;

				ApCliCtrlMsg.Status = MLME_SUCCESS;
#ifdef MAC_REPEATER_SUPPORT
				ApCliCtrlMsg.BssIdx = ifIndex;
				ApCliCtrlMsg.CliIdx = 0xFF;
#endif /* MAC_REPEATER_SUPPORT */

				MlmeEnqueue(pAd, APCLI_CTRL_STATE_MACHINE, APCLI_CTRL_PROBE_RSP,
					sizeof(APCLI_CTRL_MSG_STRUCT), &ApCliCtrlMsg, ifIndex);
				MlmeHandler(pAd);
			}
		}
		/* not to me BEACON, ignored */
	}
	/* sanity check fail, ignore this frame */

LabelErr:
	if (VarIE != NULL)
		os_free_mem(NULL, VarIE);
	if (ie_list != NULL)
		os_free_mem(NULL, ie_list);

	return;
}