/* *************************************************************************** * Ralink Tech Inc. * 5F., No.36, Taiyuan St., Jhubei City, * Hsinchu County 302, * Taiwan, R.O.C. * * (c) Copyright 2002-2010, Ralink Technology, Inc. * * All rights reserved. Ralink's source code is an unpublished work and the * use of a copyright notice does not imply otherwise. This source code * contains confidential trade secret material of Ralink Tech. Any attemp * or participation in deciphering, decoding, reverse engineering or in any * way altering the source code is stricitly prohibited, unless the prior * written consent of Ralink Technology, Inc. is obtained. *************************************************************************** Module Name: sta_iwsc Abstract: Handle IWSC for IBSS */ #ifdef IWSC_SUPPORT #include "rt_config.h" #define IWSC_SEL_REG_START_NOTITY 0 #define IWSC_SEL_REG_FINISH_NOTITY 1 #define IWSC_DEV_QUERY_REQUEST 2 #define IWSC_DEV_QUERY_RESPONSE 3 #define IWSC_ENTRY_TIME_OUT 15000 extern UCHAR IWSC_OUI[]; extern UCHAR ZERO_MAC_ADDR[]; extern UCHAR IWSC_ACTION_OUI[]; VOID IWSC_MlmeStartAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem); VOID IWSC_MlmeStopAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem); VOID IWSC_InvalidState( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem); VOID IWSC_ScanDoneAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem); VOID IWSC_ReConnectAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem); VOID IWSC_SendActionFrame( IN PRTMP_ADAPTER pAd, IN UCHAR FrameType); VOID IWSC_PeerAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem); VOID IWSC_RoleAction( IN PRTMP_ADAPTER pAd, IN INT WscConfMode); ULONG IWSC_SearchWpsApByPinMethod( IN PRTMP_ADAPTER pAd); VOID IWSC_GetConfigMethod( IN PRTMP_ADAPTER pAd, IN PUCHAR pVIE, IN INT VIELen, OUT PUSHORT pConfigMethod); VOID IWSC_PeerProbeRequest( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem); VOID IWSC_PeerProbeResponse( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem); VOID IWSC_PeerPIN( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem); VOID IWSC_BuildDevQueryFrame( IN PRTMP_ADAPTER pAd, OUT PUCHAR pOutBuf, OUT PUSHORT pIeLen); VOID IWSC_ResetIpContent( IN PRTMP_ADAPTER pAd); /* ========================================================================== Description: IWSC state machine init, including state transition Parameters: Sm - pointer to the auth state machine Note: The state machine looks like this ========================================================================== */ void IWSC_StateMachineInit( IN PRTMP_ADAPTER pAd, IN STATE_MACHINE *Sm, OUT STATE_MACHINE_FUNC Trans[]) { StateMachineInit(Sm, Trans, MAX_IWSC_STATE, MAX_IWSC_MSG, (STATE_MACHINE_FUNC)Drop, IWSC_IDLE, IWSC_MACHINE_BASE); StateMachineSetAction(Sm, IWSC_IDLE, IWSC_MT2_MLME_START, (STATE_MACHINE_FUNC)IWSC_MlmeStartAction); StateMachineSetAction(Sm, IWSC_IDLE, IWSC_MT2_PEER_ACTION_FRAME, (STATE_MACHINE_FUNC)IWSC_PeerAction); StateMachineSetAction(Sm, IWSC_IDLE, IWSC_MT2_MLME_SCAN_DONE, (STATE_MACHINE_FUNC)IWSC_ScanDoneAction); StateMachineSetAction(Sm, IWSC_IDLE, IWSC_MT2_MLME_RECONNECT, (STATE_MACHINE_FUNC)IWSC_InvalidState); StateMachineSetAction(Sm, IWSC_START, IWSC_MT2_MLME_START, (STATE_MACHINE_FUNC)IWSC_MlmeStartAction); StateMachineSetAction(Sm, IWSC_START, IWSC_MT2_MLME_STOP, (STATE_MACHINE_FUNC)IWSC_MlmeStopAction); StateMachineSetAction(Sm, IWSC_START, IWSC_MT2_PEER_PROBE_REQ, (STATE_MACHINE_FUNC)IWSC_PeerProbeRequest); StateMachineSetAction(Sm, IWSC_START, IWSC_MT2_MLME_SCAN_DONE, (STATE_MACHINE_FUNC)IWSC_ScanDoneAction); StateMachineSetAction(Sm, IWSC_START, IWSC_MT2_MLME_RECONNECT, (STATE_MACHINE_FUNC)IWSC_ReConnectAction); StateMachineSetAction(Sm, IWSC_SCAN, IWSC_MT2_MLME_START, (STATE_MACHINE_FUNC)IWSC_MlmeStartAction); StateMachineSetAction(Sm, IWSC_SCAN, IWSC_MT2_MLME_STOP, (STATE_MACHINE_FUNC)IWSC_MlmeStopAction); StateMachineSetAction(Sm, IWSC_SCAN, IWSC_MT2_PEER_PROBE_RSP, (STATE_MACHINE_FUNC)IWSC_PeerProbeResponse); StateMachineSetAction(Sm, IWSC_SCAN, IWSC_MT2_MLME_SCAN_DONE, (STATE_MACHINE_FUNC)IWSC_ScanDoneAction); StateMachineSetAction(Sm, IWSC_SCAN, IWSC_MT2_MLME_RECONNECT, (STATE_MACHINE_FUNC)IWSC_InvalidState); StateMachineSetAction(Sm, IWSC_WAIT_PIN, IWSC_MT2_PEER_PIN, (STATE_MACHINE_FUNC)IWSC_PeerPIN); StateMachineSetAction(Sm, IWSC_WAIT_PIN, IWSC_MT2_MLME_STOP, (STATE_MACHINE_FUNC)IWSC_MlmeStopAction); StateMachineSetAction(Sm, IWSC_WAIT_JOIN, IWSC_MT2_MLME_STOP, (STATE_MACHINE_FUNC)IWSC_MlmeStopAction); } VOID IWSC_InvalidState( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem) { DBGPRINT(RT_DEBUG_TRACE, ("IWSC - InvalidState (state=%ld, msg_type = %ld)\n", pAd->Mlme.IWscMachine.CurrState, pElem->MsgType)); } VOID IWSC_Init( IN IN PRTMP_ADAPTER pAd) { PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; RTMPInitTimer(pAd, &pIWscInfo->IWscT1Timer, GET_TIMER_FUNCTION(IWSC_T1TimerAction), pAd, FALSE); RTMPInitTimer(pAd, &pIWscInfo->IWscT2Timer, GET_TIMER_FUNCTION(IWSC_T2TimerAction), pAd, FALSE); RTMPInitTimer(pAd, &pIWscInfo->IWscEntryTimer, GET_TIMER_FUNCTION(IWSC_EntryTimerAction), pAd, FALSE); RTMPInitTimer(pAd, &pIWscInfo->IWscDevQueryTimer, GET_TIMER_FUNCTION(IWSC_DevQueryAction), pAd, FALSE); pIWscInfo->bIWscT1TimerRunning = FALSE; pIWscInfo->bIWscT2TimerRunning = FALSE; pIWscInfo->bIWscEntryTimerRunning = FALSE; pIWscInfo->bIWscDevQueryReqTimerRunning = FALSE; pIWscInfo->bIWscDevQueryRspTimerRunning = FALSE; pIWscInfo->DialogToken = 0; pIWscInfo->PeerDialogToken = 0; pIWscInfo->bSelRegStart = FALSE; pIWscInfo->bReStart = FALSE; pIWscInfo->IWscSmpbcAcceptCount = 0; pIWscInfo->bLimitedUI = FALSE; pIWscInfo->bSinglePIN = FALSE; pIWscInfo->bDoNotChangeBSSID = FALSE; pIWscInfo->bSendEapolStart = FALSE; pIWscInfo->IpConfMethod = (IWSC_IPV4_ASSIGNMENT | IWSC_DHCP_IPV4 | IWSC_STATIC_IPV4); pIWscInfo->IpMethod = IWSC_IPV4_ASSIGNMENT; pIWscInfo->SelfIpv4Addr = IWSC_DEFAULT_REG_IPV4_ADDR; pIWscInfo->PeerIpv4Addr = 0; pIWscInfo->RegIpv4Addr = 0; pIWscInfo->Ipv4SubMask = IWSC_DEFAULT_IPV4_SUBMASK; pIWscInfo->CurrentIpRange = IWSC_DEFAULT_IPV4_RANGE; pIWscInfo->RegDepth = 0; pIWscInfo->IpDevCount = 0; pIWscInfo->AvaSubMaskListCount = IWSC_MAX_SUB_MASK_LIST_COUNT; pIWscInfo->AvaSubMaskList[0] = IWSC_IPV4_RANGE1; pIWscInfo->AvaSubMaskList[1] = IWSC_IPV4_RANGE2; pIWscInfo->AvaSubMaskList[2] = IWSC_IPV4_RANGE3; pIWscInfo->bAssignWscIPv4 = TRUE; pIWscInfo->bDoNotStop = FALSE; pIWscInfo->SmpbcEnrolleeCount = 0; RTMPZeroMemory(pIWscInfo->RegMacAddr, MAC_ADDR_LEN); RTMPZeroMemory(pIWscInfo->IWscDevQueryReqMacAddr, MAC_ADDR_LEN); initList(&pAd->StaCfg.WscControl.WscConfiguredPeerList); NdisAllocateSpinLock(pAd, &pAd->StaCfg.WscControl.WscConfiguredPeerListSemLock); #ifdef IWSC_TEST_SUPPORT pIWscInfo->IWscDefaultSecurity = 3; pIWscInfo->bIwscSmpbcScanningOnly = FALSE; pIWscInfo->bEmptySubmaskList = FALSE; #endif // IWSC_TEST_SUPPORT // } VOID IWSC_Stop( IN PRTMP_ADAPTER pAd, IN BOOLEAN bSendNotification) { PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; BOOLEAN bCancelled; DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_Stop\n")); if (pIWscInfo->bIWscT1TimerRunning) { pIWscInfo->bIWscT1TimerRunning = FALSE; RTMPCancelTimer(&pIWscInfo->IWscT1Timer, &bCancelled); } if (pIWscInfo->bIWscT2TimerRunning) { pIWscInfo->bIWscT2TimerRunning = FALSE; RTMPCancelTimer(&pIWscInfo->IWscT2Timer, &bCancelled); } if (pIWscInfo->bIWscEntryTimerRunning) { pIWscInfo->bIWscEntryTimerRunning = FALSE; RTMPCancelTimer(&pIWscInfo->IWscEntryTimer, &bCancelled); } if (pWpsCtrl->WscPBCTimerRunning) { pWpsCtrl->WscPBCTimerRunning = FALSE; RTMPCancelTimer(&pWpsCtrl->WscPBCTimer, &bCancelled); } pIWscInfo->IWscSmpbcAcceptCount = 0; if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_REMOVE_IN_PROGRESS) == FALSE) { AsicDisableSync(pAd); pAd->StaCfg.WpsIEBeacon.ValueLen = 0; pAd->StaCfg.WpsIEProbeResp.ValueLen = 0; MakeIbssBeacon(pAd); /* re-build BEACON frame */ AsicEnableIbssSync(pAd); /* copy BEACON frame to on-chip memory */ WscStop(pAd, #ifdef CONFIG_AP_SUPPORT FALSE, #endif /* CONFIG_AP_SUPPORT */ pWpsCtrl); } if (bSendNotification) { /* Send Selected Registrar Finish Notification (multicast action frame) */ IWSC_SendActionFrame(pAd, IWSC_SEL_REG_FINISH_NOTITY); } pAd->Mlme.IWscMachine.CurrState = IWSC_IDLE; DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_Stop\n")); } /**************************************************** IWSC Timer Function Begin ****************************************************/ VOID IWSC_T1TimerAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext; PWSC_CTRL pWpsCtrl = NULL; DBGPRINT(RT_DEBUG_TRACE, ("!!! IWSC_T1TimerAction !!!\n")); if (pAd) { pWpsCtrl = &pAd->StaCfg.WscControl; if (pWpsCtrl) { pAd->StaCfg.IWscInfo.bDoNotStop = FALSE; if ((pWpsCtrl->WscConfMode == WSC_REGISTRAR) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { /* Send Selected Registrar Finish Notification (multicast action frame) */ IWSC_Stop(pAd, TRUE); } else IWSC_Stop(pAd, FALSE); pWpsCtrl->WscStatus = STATUS_WSC_IDLE; #ifdef IWSC_TEST_SUPPORT pAd->StaCfg.IWscInfo.IWscConfMode = WSC_DISABLE; #endif // IWSC_TEST_SUPPORT // RTMPSendWirelessEvent(pAd, IW_IWSC_T1_TIMER_TIMEOUT, NULL, pWpsCtrl->EntryIfIdx, 0); } else DBGPRINT(RT_DEBUG_ERROR, ("!!! IWSC_T1TimerAction - pWpsCtrl is null !!!\n")); } else DBGPRINT(RT_DEBUG_ERROR, ("!!! IWSC_T1TimerAction - pAd is null !!!\n")); } VOID IWSC_T2TimerAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext; PWSC_CTRL pWpsCtrl = NULL; DBGPRINT(RT_DEBUG_TRACE, ("!!! IWSC_T2TimerAction - Become Enrollee !!!\n")); if (pAd) { pWpsCtrl = &pAd->StaCfg.WscControl; if (pWpsCtrl) { RTMPSendWirelessEvent(pAd, IW_IWSC_T2_TIMER_TIMEOUT, NULL, pWpsCtrl->EntryIfIdx, 0); IWSC_RoleAction(pAd, WSC_ENROLLEE); pAd->Mlme.IWscMachine.CurrState = IWSC_SCAN; } else DBGPRINT(RT_DEBUG_ERROR, ("!!! IWSC_T2TimerAction - pWpsCtrl is null !!!\n")); } else DBGPRINT(RT_DEBUG_ERROR, ("!!! IWSC_T2TimerAction - pAd is null !!!\n")); } VOID IWSC_EntryTimerAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext; PIWSC_INFO pIWscInfo = NULL; DBGPRINT(RT_DEBUG_TRACE, ("!!! IWSC_EntryTimerAction !!!\n")); if (pAd) { pIWscInfo = &pAd->StaCfg.IWscInfo; if (pIWscInfo) { pIWscInfo->bIWscEntryTimerRunning = FALSE; WscBuildProbeRespIE(pAd, WSC_MSGTYPE_REGISTRAR, pAd->StaCfg.WscControl.WscConfStatus, TRUE, DEV_PASS_ID_SMPBC, pAd->StaCfg.WscControl.WscConfigMethods, BSS0, NULL, 0, STA_MODE); RTMPSendWirelessEvent(pAd, IW_IWSC_ENTRY_TIMER_TIMEOUT, NULL, pAd->StaCfg.WscControl.EntryIfIdx, 0); } else DBGPRINT(RT_DEBUG_ERROR, ("!!! IWSC_EntryTimerAction - pIWscInfo is null !!!\n")); } else DBGPRINT(RT_DEBUG_ERROR, ("!!! IWSC_EntryTimerAction - pAd is null !!!\n")); } VOID IWSC_DevQueryAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)FunctionContext; PIWSC_INFO pIWscInfo = NULL; DBGPRINT(RT_DEBUG_TRACE, ("!!! IWSC_DevQueryAction !!!\n")); if (pAd) { pIWscInfo = &pAd->StaCfg.IWscInfo; if (pIWscInfo) { if (pIWscInfo->bIWscDevQueryReqTimerRunning) { pIWscInfo->bIWscDevQueryReqTimerRunning = FALSE; IWSC_SendActionFrame(pAd, IWSC_DEV_QUERY_REQUEST); RTMPusecDelay(200000); // 200 ms IWSC_SendActionFrame(pAd, IWSC_DEV_QUERY_REQUEST); RTMPusecDelay(200000); // 200 ms IWSC_SendActionFrame(pAd, IWSC_DEV_QUERY_REQUEST); } if (pIWscInfo->bIWscDevQueryRspTimerRunning) { pIWscInfo->bIWscDevQueryRspTimerRunning = FALSE; IWSC_SendActionFrame(pAd, IWSC_DEV_QUERY_RESPONSE); } } else DBGPRINT(RT_DEBUG_ERROR, ("!!! IWSC_DevQueryAction - pIWscInfo is null !!!\n")); } else DBGPRINT(RT_DEBUG_ERROR, ("!!! IWSC_DevQueryAction - pAd is null !!!\n")); } /**************************************************** IWSC Timer Function End ****************************************************/ VOID IWSC_MlmeStartAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem) { PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; /* Check IWSC State */ if (pAd->Mlme.IWscMachine.CurrState != IWSC_IDLE) { /* Stop IWSC */ IWSC_Stop(pAd, FALSE); } RTMPSetTimer(&pIWscInfo->IWscT1Timer, WSC_TWO_MINS_TIME_OUT); pIWscInfo->bIWscT1TimerRunning = TRUE; WscInitRegistrarPair(pAd, pWpsCtrl, BSS0); WscGetRegDataPIN(pAd, pWpsCtrl->WscPinCode, pWpsCtrl); pWpsCtrl->RegData.ReComputePke = 1; if (!OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { IWSC_ResetIpContent(pAd); } pIWscInfo->SmpbcEnrolleeCount = 0; pIWscInfo->IWscSmpbcAcceptCount = 0; NdisZeroMemory(pWpsCtrl->EntryAddr, MAC_ADDR_LEN); RTMP_SEM_LOCK(&pWpsCtrl->WscPeerListSemLock); WscClearPeerList(&pWpsCtrl->WscPeerList); RTMP_SEM_UNLOCK(&pWpsCtrl->WscPeerListSemLock); RTMP_SEM_LOCK(&pWpsCtrl->WscConfiguredPeerListSemLock); WscClearPeerList(&pWpsCtrl->WscConfiguredPeerList); RTMP_SEM_UNLOCK(&pWpsCtrl->WscConfiguredPeerListSemLock); if (pWpsCtrl->WscMode == WSC_SMPBC_MODE) { if (pWpsCtrl->WscConfMode == WSC_REGISTRAR) { RTMPSetTimer(&pIWscInfo->IWscEntryTimer, IWSC_ENTRY_TIME_OUT); pIWscInfo->bIWscEntryTimerRunning = TRUE; IWSC_RoleAction(pAd, WSC_REGISTRAR); IWSC_SendActionFrame(pAd, IWSC_SEL_REG_START_NOTITY); pAd->Mlme.IWscMachine.CurrState = IWSC_START; } else { IWSC_RoleAction(pAd, WSC_ENROLLEE); pAd->Mlme.IWscMachine.CurrState = IWSC_SCAN; } } else { #ifdef IWSC_TEST_SUPPORT if (pIWscInfo->IWscConfMode == WSC_ENROLLEE) { IWSC_RoleAction(pAd, WSC_ENROLLEE); pAd->Mlme.IWscMachine.CurrState = IWSC_SCAN; } else #endif // IWSC_TEST_SUPPORT // { IWSC_RoleAction(pAd, WSC_REGISTRAR); if (OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { /* [A member of IBSS] - Send Selected Registrar Start Notification (multicast action frame) */ IWSC_SendActionFrame(pAd, IWSC_SEL_REG_START_NOTITY); } else { if ((pAd->StaCfg.IWscInfo.bSinglePIN == FALSE) #ifdef IWSC_TEST_SUPPORT && (pIWscInfo->IWscConfMode == WSC_DISABLE) #endif // IWSC_TEST_SUPPORT // ) { /* [!A member of IBSS] */ UCHAR RandomTime; RandomTime = RandomByte(pAd) & 0x3C; if (RandomTime > 60) RandomTime = 60; else if (RandomTime < 20) RandomTime = 20; DBGPRINT(RT_DEBUG_TRACE, ("RandomTime = %d\n", RandomTime)); RTMPSetTimer(&pIWscInfo->IWscT2Timer, (RandomTime*100)); pIWscInfo->bIWscT2TimerRunning = TRUE; } } pAd->Mlme.IWscMachine.CurrState = IWSC_START; } } pWpsCtrl->bWscTrigger = TRUE; } VOID IWSC_MlmeStopAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem) { PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; if (pAd->StaCfg.IWscInfo.bSinglePIN && pAd->StaCfg.IWscInfo.bDoNotStop) { DBGPRINT(RT_DEBUG_TRACE, ("SinglePIN registrar now, keep going!!\n")); pWpsCtrl->WscConfMode = WSC_REGISTRAR; pWpsCtrl->RegData.ReComputePke = 1; pWpsCtrl->bWscTrigger = TRUE; pWpsCtrl->WscState = WSC_STATE_LINK_UP; pWpsCtrl->WscStatus = STATUS_WSC_LINK_UP; return; } #ifdef IWSC_TEST_SUPPORT pAd->StaCfg.IWscInfo.IWscConfMode = WSC_DISABLE; #endif // IWSC_TEST_SUPPORT // /* Check IWSC State */ if (pAd->Mlme.IWscMachine.CurrState != IWSC_IDLE) { /* Stop IWSC */ if ((pWpsCtrl->WscConfMode == WSC_REGISTRAR) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { /* Send Selected Registrar Finish Notification (multicast action frame) */ IWSC_Stop(pAd, TRUE); } else IWSC_Stop(pAd, FALSE); } } VOID IWSC_ScanDoneAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem) { PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; UCHAR RandomTime; if (pAd->Mlme.IWscMachine.CurrState != IWSC_SCAN) { if (pAd->Mlme.IWscMachine.CurrState != IWSC_IDLE) DBGPRINT(RT_DEBUG_TRACE, ("IWSC_ScanDoneAction:: CurrState = %ld\n", pAd->Mlme.IWscMachine.CurrState)); return; } DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_ScanDoneAction\n")); if (pWpsCtrl->WscMode == WSC_PBC_MODE) { if (WscPBCExec(pAd, FALSE, pWpsCtrl) == FALSE) { if (pWpsCtrl->WscPBCBssCount > 1) { IWSC_Stop(pAd, FALSE); } else { #ifdef IWSC_TEST_SUPPORT if (pAd->StaCfg.IWscInfo.IWscConfMode != WSC_ENROLLEE) #endif /* IWSC_TEST_SUPPORT */ { IWSC_RoleAction(pAd, WSC_REGISTRAR); RandomTime = RandomByte(pAd) & 0x3C; if (RandomTime > 60) RandomTime = 60; else if (RandomTime < 20) RandomTime = 20; DBGPRINT(RT_DEBUG_TRACE, ("RandomTime = %d\n", RandomTime)); RTMPSetTimer(&pAd->StaCfg.IWscInfo.IWscT2Timer, (RandomTime*100)); pAd->StaCfg.IWscInfo.bIWscT2TimerRunning = TRUE; pAd->Mlme.IWscMachine.CurrState = IWSC_START; } #ifdef IWSC_TEST_SUPPORT else { RTMPSetTimer(&pWpsCtrl->WscScanTimer, 1000); pWpsCtrl->WscScanTimerRunning = TRUE; } #endif /* IWSC_TEST_SUPPORT */ } } else { BOOLEAN bCancel; if (pWpsCtrl->WscPBCTimerRunning) RTMPCancelTimer(&pWpsCtrl->WscPBCTimer, &bCancel); pAd->Mlme.IWscMachine.CurrState = IWSC_START; pAd->StaCfg.IWscInfo.bSendEapolStart = TRUE; } } else if (pWpsCtrl->WscMode == WSC_SMPBC_MODE) { WscPBCExec(pAd, FALSE, pWpsCtrl); #ifdef IWSC_TEST_SUPPORT if (pAd->StaCfg.IWscInfo.bIwscSmpbcScanningOnly) { RTMPSetTimer(&pWpsCtrl->WscScanTimer, 1000); pWpsCtrl->WscScanTimerRunning = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_ScanDoneAction\n")); return; } #endif /* IWSC_TEST_SUPPORT */ if (pWpsCtrl->WscPBCBssCount == 1) { pWpsCtrl->WscStatus = WSC_STATE_START; pAd->Mlme.IWscMachine.CurrState = IWSC_START; pAd->StaCfg.IWscInfo.bSendEapolStart = TRUE; } else if (pWpsCtrl->WscPBCBssCount == 0) { RTMPSetTimer(&pWpsCtrl->WscScanTimer, 1000); pWpsCtrl->WscScanTimerRunning = TRUE; } else IWSC_Stop(pAd, FALSE); } else { { #ifdef IWSC_TEST_SUPPORT if (pAd->StaCfg.IWscInfo.IWscConfMode == WSC_ENROLLEE) { WscScanExec(pAd); } else #endif // IWSC_TEST_SUPPORT // { IWSC_RoleAction(pAd, WSC_REGISTRAR); RandomTime = RandomByte(pAd) & 0x3C; if (RandomTime > 60) RandomTime = 60; else if (RandomTime < 20) RandomTime = 20; DBGPRINT(RT_DEBUG_TRACE, ("RandomTime = %d\n", RandomTime)); RTMPSetTimer(&pAd->StaCfg.IWscInfo.IWscT2Timer, (RandomTime*100)); pAd->StaCfg.IWscInfo.bIWscT2TimerRunning = TRUE; pAd->Mlme.IWscMachine.CurrState = IWSC_START; } } } DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_ScanDoneAction\n")); } VOID IWSC_ReConnectAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem) { PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; DBGPRINT(RT_DEBUG_TRACE, ("-----> %s\n", __FUNCTION__)); MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID, sizeof(NDIS_802_11_SSID), (VOID *)&pWpsCtrl->WscSsid, 0); RTMP_MLME_HANDLER(pAd); DBGPRINT(RT_DEBUG_TRACE, ("<----- %s\n", __FUNCTION__)); } VOID IWSC_BuildSelRegStartNotification( IN PRTMP_ADAPTER pAd, OUT PUCHAR pOutBuf, OUT PUSHORT pIeLen) { // UCHAR Data[512]; // change array to pointer UCHAR *Data = NULL; PUCHAR pData; INT Len = 0, templen = 0; PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWpsCtrl->RegData; USHORT tempVal = 0; USHORT ConfigError = htons(0); WSC_IE_HEADER ieHdr; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&Data, 512); if (Data == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_BuildSelRegStartNotification\n")); // WSC IE HEader ieHdr.elemId = 221; ieHdr.length = 4; ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50; ieHdr.oui[2] = 0xF2; ieHdr.oui[3] = 0x10; pData = (PUCHAR) &Data[0]; Len = 0; /* Version */ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0); pData += templen; Len += templen; /* Request Type */ tempVal = WSC_MSGTYPE_REGISTRAR; templen = AppendWSCTLV(WSC_ID_REQ_TYPE, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; /* Config method */ tempVal = htons(0x008c); templen = AppendWSCTLV(WSC_ID_CONFIG_METHODS, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; /* UUID */ templen = AppendWSCTLV(WSC_ID_UUID_E, pData, pReg->SelfInfo.Uuid, 0); pData += templen; Len += templen; /* Primary device type */ templen = AppendWSCTLV(WSC_ID_PRIM_DEV_TYPE, pData, pReg->SelfInfo.PriDeviceType, 0); pData += templen; Len += templen; /* RF band, shall change based on current channel */ templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, &pReg->SelfInfo.RfBand, 0); pData += templen; Len += templen; /* Config error */ templen = AppendWSCTLV(WSC_ID_CONFIG_ERROR, pData, (UINT8 *)&ConfigError, 0); pData += templen; Len += templen; /* Device Password ID */ if (pWpsCtrl->WscMode == WSC_PIN_MODE) tempVal = DEV_PASS_ID_PIN;//cpu2be16(DEV_PASS_ID_PIN); else tempVal = cpu2be16(DEV_PASS_ID_PBC); templen = AppendWSCTLV(WSC_ID_DEVICE_PWD_ID, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; /* MAC address */ templen = AppendWSCTLV(WSC_ID_MAC_ADDR, pData, pReg->SelfInfo.MacAddr, 0); pData += templen; Len += templen; ieHdr.length = ieHdr.length + Len; RTMPMoveMemory(pOutBuf, &ieHdr, sizeof(WSC_IE_HEADER)); RTMPMoveMemory(pOutBuf + sizeof(WSC_IE_HEADER), Data, Len); *pIeLen = (USHORT)(sizeof(WSC_IE_HEADER) + Len); if (Data != NULL) os_free_mem(NULL, Data); DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_BuildSelRegStartNotification\n")); } VOID IWSC_BuildSelRegFinishNotification( IN PRTMP_ADAPTER pAd, OUT PUCHAR pOutBuf, OUT PUSHORT pIeLen) { // UCHAR Data[512]; UCHAR *Data = NULL; PUCHAR pData; INT Len = 0, templen = 0; PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWpsCtrl->RegData; WSC_IE_HEADER ieHdr; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&Data, 512); if (Data == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_BuildSelRegFinishNotification\n")); // WSC IE HEader ieHdr.elemId = 221; ieHdr.length = 4; ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50; ieHdr.oui[2] = 0xF2; ieHdr.oui[3] = 0x10; pData = (PUCHAR) &Data[0]; Len = 0; /* Version */ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0); pData += templen; Len += templen; /* Simple Config State */ templen = AppendWSCTLV(WSC_ID_SC_STATE, pData, (UINT8 *)&pWpsCtrl->WscConfStatus, 0); pData += templen; Len += templen; templen = AppendWSCTLV(WSC_ID_MAC_ADDR, pData, &pAd->CurrentAddress[0], 0); pData += templen; Len += templen; ieHdr.length = ieHdr.length + Len; RTMPMoveMemory(pOutBuf, &ieHdr, sizeof(WSC_IE_HEADER)); RTMPMoveMemory(pOutBuf + sizeof(WSC_IE_HEADER), Data, Len); *pIeLen = sizeof(WSC_IE_HEADER) + Len; if (Data != NULL) os_free_mem(NULL, Data); DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_BuildSelRegFinishNotification\n")); } /* IWSC Public Action Frame Format ----------------------------------------------------------------------------------------------- Field Size Value ----------------------------------------------------------------------------------------------- Category 1 Octet 0x04 ----------------------------------------------------------------------------------------------- Action field 1 Octet 0xDD ----------------------------------------------------------------------------------------------- OUI 3 Octets 0x50 0x6F 0x9A ----------------------------------------------------------------------------------------------- OUI type 1 Octet 0x10 ----------------------------------------------------------------------------------------------- OUI Subtype 1 Octet 0 - Selected Registrar Start Notification 1 - Selected Registrar Finish Notification 2 - Device Query Request 3 - Device Query Response 4 ~ 255 - Reserved ----------------------------------------------------------------------------------------------- Dialog Token 1 Octet nonzero value (to identify the request/response transaction ----------------------------------------------------------------------------------------------- Elements variable IWSC IE (It has the Element ID(0xDD), Length, IWSC OUI(0x00 0x50 0xF2 0x10) ----------------------------------------------------------------------------------------------- */ VOID IWSC_SendActionFrame( IN PRTMP_ADAPTER pAd, IN UCHAR FrameType) { HEADER_802_11 ActHdr; PUCHAR pOutBuffer = NULL; ULONG FrameLen = 0; UCHAR Category = CATEGORY_PUBLIC; UCHAR Action = 9; PUCHAR pWscBuf = NULL; USHORT WscIeLen = 0; ULONG WscTmpLen = 0; PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; NDIS_STATUS NStatus; NStatus = MlmeAllocateMemory(pAd, &pOutBuffer); if (NStatus != NDIS_STATUS_SUCCESS) { DBGPRINT(RT_DEBUG_TRACE,("IWSC_SendStartNotification:: allocate memory failed \n")); return; } if (FrameType == IWSC_DEV_QUERY_RESPONSE) ActHeaderInit(pAd, &ActHdr, pIWscInfo->IWscDevQueryReqMacAddr, pAd->CurrentAddress, pAd->CommonCfg.Bssid); else ActHeaderInit(pAd, &ActHdr, BROADCAST_ADDR, pAd->CurrentAddress, pAd->CommonCfg.Bssid); if (pIWscInfo->DialogToken == 0) pIWscInfo->DialogToken = 1; else pIWscInfo->DialogToken++; MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(HEADER_802_11), &ActHdr, 1, &Category, 1, &Action, 4, IWSC_ACTION_OUI, 1, &FrameType, 1, &pIWscInfo->DialogToken, END_OF_ARGS); os_alloc_mem(NULL, &pWscBuf, 512); if( pWscBuf != NULL) { NdisZeroMemory(pWscBuf, 512); if (FrameType == IWSC_SEL_REG_START_NOTITY) IWSC_BuildSelRegStartNotification(pAd, pWscBuf, &WscIeLen); else if (FrameType == IWSC_SEL_REG_FINISH_NOTITY) IWSC_BuildSelRegFinishNotification(pAd, pWscBuf, &WscIeLen); else if (FrameType == IWSC_DEV_QUERY_REQUEST) IWSC_BuildDevQueryFrame(pAd, pWscBuf, &WscIeLen); else if (FrameType == IWSC_DEV_QUERY_RESPONSE) IWSC_BuildDevQueryFrame(pAd, pWscBuf, &WscIeLen); MakeOutgoingFrame(pOutBuffer + FrameLen, &WscTmpLen, WscIeLen, pWscBuf, END_OF_ARGS); FrameLen += WscTmpLen; os_free_mem(NULL, pWscBuf); } else DBGPRINT(RT_DEBUG_WARN, ("%s:: WscBuf Allocate failed!\n", __FUNCTION__)); MiniportMMRequest(pAd, 0, pOutBuffer, FrameLen); MlmeFreeMemory(pAd, pOutBuffer); } VOID IWSC_PeerAction( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem) { UCHAR Token = pElem->Msg[LENGTH_802_11+7]; UCHAR FrameType = pElem->Msg[LENGTH_802_11+6]; PUCHAR pData = pElem->Msg+(LENGTH_802_11+8); PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; INT Len = 0; INT TotalLen = (INT)pElem->MsgLen - (LENGTH_802_11+8); USHORT RegDPID; USHORT RegCfgMethods; UINT8 ReqType = 0; UCHAR PeerMAC[MAC_ADDR_LEN]; DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_PeerAction\n")); /* Marvell STA always send same non-zero Token value, thus we don't need to check Token value here. */ { /* IWSC Element may not be first one element in Action frame. */ pIWscInfo->PeerDialogToken = Token; for (;;) { Len = (INT)*(pData + 1); /*hex_dump("sn - pData", pData, Len+2);*/ pData = pData + 2; if (NdisEqualMemory(pData, IWSC_OUI, 4)) { Len -= 4; // OUI Length pData = pData + 4; break; } TotalLen -= (Len + 2); // 2: ID + Len if (TotalLen <= 0) { DBGPRINT(RT_DEBUG_TRACE, ("No IWSC IE!\n<----- IWSC_PeerAction\n")); return; } pData = pData + Len; } hex_dump("pData", pData, Len); while (Len > 0) { WSC_IE WscIE; PWSC_IE pWscIE; NdisMoveMemory(&WscIE, pData, sizeof(WSC_IE)); /* Check for WSC IEs */ pWscIE = &WscIE; if (be2cpu16(pWscIE->Type) == WSC_ID_REQ_TYPE) { ReqType = *(pData + 4); } if (be2cpu16(pWscIE->Type) == WSC_ID_SEL_REG_CFG_METHODS) { NdisMoveMemory(&RegCfgMethods, pData + 4, sizeof(USHORT)); RegCfgMethods = be2cpu16(RegCfgMethods); } if (be2cpu16(pWscIE->Type) == WSC_ID_DEVICE_PWD_ID) { NdisMoveMemory(&RegDPID, pData + 4, sizeof(USHORT)); RegDPID = be2cpu16(RegDPID); } if (be2cpu16(pWscIE->Type) == WSC_ID_MAC_ADDR) { RTMPMoveMemory(PeerMAC, pData + 4, MAC_ADDR_LEN); } /* Set the offset Since Type and Length are both short type, we need to offset 4, not 2 */ pData += (be2cpu16(pWscIE->Length) + 4); Len -= (be2cpu16(pWscIE->Length) + 4); } if (FrameType == IWSC_SEL_REG_START_NOTITY) { DBGPRINT(RT_DEBUG_TRACE, ("Receive SelRegStartNotification from %02X:%02X:%02X:%02X:%02X:%02X!\n", PeerMAC[0], PeerMAC[1], PeerMAC[2], PeerMAC[3], PeerMAC[4], PeerMAC[5])); pIWscInfo->bSelRegStart = TRUE; RTMPMoveMemory(pIWscInfo->RegMacAddr, PeerMAC, MAC_ADDR_LEN); WscBuildProbeRespIE(pAd, WSC_MSGTYPE_IWSC_NOTIFIER, pAd->StaCfg.WscControl.WscConfStatus, TRUE, RegDPID, RegCfgMethods, 0, NULL, 0, STA_MODE); } else if (FrameType == IWSC_SEL_REG_FINISH_NOTITY) { DBGPRINT(RT_DEBUG_TRACE, ("Receive SelRegFinishNotification from %02X:%02X:%02X:%02X:%02X:%02X!\n", PeerMAC[0], PeerMAC[1], PeerMAC[2], PeerMAC[3], PeerMAC[4], PeerMAC[5])); if (NdisEqualMemory(pIWscInfo->RegMacAddr, PeerMAC, MAC_ADDR_LEN)) { pIWscInfo->bSelRegStart = FALSE; NdisZeroMemory(pIWscInfo->RegMacAddr, MAC_ADDR_LEN); } if (pAd->StaCfg.WscControl.bWscTrigger == FALSE) pAd->StaCfg.WpsIEProbeResp.ValueLen = 0; } else if (FrameType == IWSC_DEV_QUERY_REQUEST) { UCHAR RandomVal = RandomByte(pAd); MAC_TABLE_ENTRY *pEntry; DBGPRINT(RT_DEBUG_TRACE, ("Receive Device Query Request from %02X:%02X:%02X:%02X:%02X:%02X!\n", PeerMAC[0], PeerMAC[1], PeerMAC[2], PeerMAC[3], PeerMAC[4], PeerMAC[5])); if (RandomVal < 20) RandomVal = 20; if (RandomVal > 50) RandomVal = 50; NdisMoveMemory(pIWscInfo->IWscDevQueryReqMacAddr, PeerMAC, MAC_ADDR_LEN); RTMPSetTimer(&pIWscInfo->IWscDevQueryTimer, RandomVal*10); pIWscInfo->bIWscDevQueryRspTimerRunning = TRUE; #ifdef IWSC_TEST_SUPPORT if (pAd->StaCfg.IWscInfo.bBlockConnection) return; #endif /* IWSC_TEST_SUPPORT */ pEntry = MacTableLookup(pAd, PeerMAC); if (pEntry == NULL) { // Another adhoc joining, add to our MAC table. pEntry = MacTableInsertEntry(pAd, PeerMAC, BSS0, OPMODE_STA, FALSE); } if (pEntry) { #ifdef ADHOC_WPA2PSK_SUPPORT //Adhoc support WPA2PSK by Eddy if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) && (pEntry->WPA_Authenticator.WpaState < AS_INITPSK)) { INT len, i; BOOLEAN bHigherMAC = FALSE; pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; NdisZeroMemory(&pEntry->WPA_Supplicant.ReplayCounter, LEN_KEY_DESC_REPLAY); NdisZeroMemory(&pEntry->WPA_Authenticator.ReplayCounter, LEN_KEY_DESC_REPLAY); pEntry->WPA_Authenticator.WpaState = AS_INITPSK; pEntry->WPA_Supplicant.WpaState = AS_INITPSK; pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_PSK; // collapse into the ADHOC network which has bigger BSSID value. for (i = 0; i < 6; i++) { if (PeerMAC[i] > pAd->CurrentAddress[i]) { bHigherMAC = TRUE; break; } else if (PeerMAC[i] < pAd->CurrentAddress[i]) break; } hex_dump("IWSC_PeerAction:: PeerMAC", PeerMAC, MAC_ADDR_LEN); hex_dump("IWSC_PeerAction:: pAd->CurrentAddress", pAd->CurrentAddress, MAC_ADDR_LEN); pEntry->bPeerHigherMAC = bHigherMAC; if (pEntry->bPeerHigherMAC == FALSE) { /* My MAC address is higher than peer's MAC address. */ DBGPRINT(RT_DEBUG_TRACE, ("%s - EnqueueStartForPSKTimer.\n", __FUNCTION__)); RTMPSetTimer(&pEntry->EnqueueStartForPSKTimer, ENQUEUE_EAPOL_START_TIMER); pEntry->bPeerHigherMAC = FALSE; } } else #endif // ADHOC_WPA2PSK_SUPPORT // { if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) pEntry->PortSecured = WPA_802_1X_PORT_SECURED; } } } else if (FrameType == IWSC_DEV_QUERY_RESPONSE) { MAC_TABLE_ENTRY *pEntry; DBGPRINT(RT_DEBUG_TRACE, ("Receive Device Query Response from %02X:%02X:%02X:%02X:%02X:%02X!\n", PeerMAC[0], PeerMAC[1], PeerMAC[2], PeerMAC[3], PeerMAC[4], PeerMAC[5])); #ifdef IWSC_TEST_SUPPORT if (pAd->StaCfg.IWscInfo.bBlockConnection) return; #endif /* IWSC_TEST_SUPPORT */ pEntry = MacTableLookup(pAd, PeerMAC); if (pEntry == NULL) { // Another adhoc joining, add to our MAC table. pEntry = MacTableInsertEntry(pAd, PeerMAC, BSS0, OPMODE_STA, FALSE); } if (pEntry) { #ifdef ADHOC_WPA2PSK_SUPPORT //Adhoc support WPA2PSK by Eddy if ((pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPA2PSK) && (pEntry->WPA_Authenticator.WpaState < AS_INITPSK)) { INT len, i; BOOLEAN bHigherMAC = FALSE; pEntry->PortSecured = WPA_802_1X_PORT_NOT_SECURED; NdisZeroMemory(&pEntry->WPA_Supplicant.ReplayCounter, LEN_KEY_DESC_REPLAY); NdisZeroMemory(&pEntry->WPA_Authenticator.ReplayCounter, LEN_KEY_DESC_REPLAY); pEntry->WPA_Authenticator.WpaState = AS_INITPSK; pEntry->WPA_Supplicant.WpaState = AS_INITPSK; pEntry->EnqueueEapolStartTimerRunning = EAPOL_START_PSK; // collapse into the ADHOC network which has bigger BSSID value. for (i = 0; i < 6; i++) { if (PeerMAC[i] > pAd->CurrentAddress[i]) { bHigherMAC = TRUE; break; } else if (PeerMAC[i] < pAd->CurrentAddress[i]) break; } hex_dump("IWSC_PeerAction:: PeerMAC", PeerMAC, MAC_ADDR_LEN); hex_dump("IWSC_PeerAction:: pAd->CurrentAddress", pAd->CurrentAddress, MAC_ADDR_LEN); pEntry->bPeerHigherMAC = bHigherMAC; if (pEntry->bPeerHigherMAC == FALSE) { /* My MAC address is higher than peer's MAC address. */ DBGPRINT(RT_DEBUG_TRACE, ("%s - EnqueueStartForPSKTimer.\n", __FUNCTION__)); RTMPSetTimer(&pEntry->EnqueueStartForPSKTimer, ENQUEUE_EAPOL_START_TIMER); pEntry->bPeerHigherMAC = FALSE; } } else #endif // ADHOC_WPA2PSK_SUPPORT // { if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) pEntry->PortSecured = WPA_802_1X_PORT_SECURED; } } } else { DBGPRINT(RT_DEBUG_TRACE, ("Unknow Frame Type!\n")); } } DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_PeerAction\n")); } VOID IWSC_PeerProbeRequest( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem) { PWSC_CTRL pWscCtrl = &pAd->StaCfg.WscControl; PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; USHORT PeerConfigMethod = 0; USHORT ConfigMethod = 0; BOOLEAN Cancelled; USHORT DPID = 0; if (pWscCtrl->WscConfMode != WSC_REGISTRAR) { DBGPRINT(RT_DEBUG_ERROR, ("IWSC_PeerProbeRequest:: Not Registrar now(WscConfMode = %d)\n" , pWscCtrl->WscConfMode)); return; } DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_PeerProbeRequest\n")); NdisMoveMemory(&PeerConfigMethod, pElem->Msg, pElem->MsgLen); if (pIWscInfo->bIWscT2TimerRunning) { RTMPCancelTimer(&pIWscInfo->IWscT2Timer, &Cancelled); pIWscInfo->bIWscT2TimerRunning = FALSE; } if (pWscCtrl->WscMode == WSC_PIN_MODE) { if (PeerConfigMethod & WPS_CONFIG_METHODS_KEYPAD) { if (pIWscInfo->bSinglePIN == FALSE) { pWscCtrl->WscEnrolleePinCode = WscRandomGeneratePinCode(pAd, BSS0); pWscCtrl->WscEnrolleePinCodeLen = 8; pWscCtrl->WscPinCodeLen = 8; pWscCtrl->WscStatus = STATUS_WSC_IBSS_NEW_RANDOM_PIN; } else pWscCtrl->WscStatus = STATUS_WSC_IBSS_FIXED_PIN; WscGetRegDataPIN(pAd, pWscCtrl->WscEnrolleePinCode, pWscCtrl); DBGPRINT(RT_DEBUG_TRACE, ("IWSC_PeerProbeRequest:: WscPinCode = %08d\n", pWscCtrl->WscPinCode)); } else { if (pAd->StaCfg.IWscInfo.bLimitedUI) { DBGPRINT(RT_DEBUG_ERROR, ("IWSC_PeerProbeRequest:: Both devices are limited UI. Shall we change to use PBC mode?\n")); IWSC_Stop(pAd, FALSE); return; } else { pWscCtrl->WscPinCode = 0; pWscCtrl->WscStatus = STATUS_WSC_WAIT_PIN_CODE; DBGPRINT(RT_DEBUG_TRACE, ("IWSC_PeerProbeRequest:: Please input Peer's PIN\n")); } } if (PeerConfigMethod & WPS_CONFIG_METHODS_KEYPAD) { DPID = DEV_PASS_ID_REG; ConfigMethod = WPS_CONFIG_METHODS_DISPLAY; } else { DPID = DEV_PASS_ID_PIN; ConfigMethod = (WPS_CONFIG_METHODS_DISPLAY | WPS_CONFIG_METHODS_KEYPAD); } AsicDisableSync(pAd); WscBuildBeaconIE(pAd, pWscCtrl->WscConfStatus, TRUE, DPID, ConfigMethod, BSS0, NULL, 0, STA_MODE); MakeIbssBeacon(pAd); /* re-build BEACON frame */ AsicEnableIbssSync(pAd); /* copy BEACON frame to on-chip memory */ WscBuildProbeRespIE(pAd, WSC_MSGTYPE_REGISTRAR, pWscCtrl->WscConfStatus, TRUE, DPID, ConfigMethod, BSS0, NULL, 0, STA_MODE); } pAd->Mlme.IWscMachine.CurrState = IWSC_WAIT_JOIN; DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_PeerProbeRequest\n")); return; } VOID IWSC_PeerProbeResponse( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem) { PWSC_CTRL pWscCtrl = &pAd->StaCfg.WscControl; PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; USHORT PeerConfigMethod = 0; BOOLEAN Cancelled; if (pWscCtrl->WscConfMode != WSC_ENROLLEE) { DBGPRINT(RT_DEBUG_ERROR, ("IWSC_PeerProbeResponse:: Not Enrollee now(WscConfMode = %d)\n" , pWscCtrl->WscConfMode)); return; } DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_PeerProbeResponse\n")); if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_BSS_SCAN_IN_PROGRESS)) { RTMPCancelTimer(&pAd->MlmeAux.ScanTimer, &Cancelled); pAd->MlmeAux.Channel = 0; // Change back to original channel in case of doing scan AsicSwitchChannel(pAd, pAd->CommonCfg.Channel, FALSE); AsicLockChannel(pAd, pAd->CommonCfg.Channel); // Resume MSDU which is turned off durning scan RTMPResumeMsduTransmission(pAd); pAd->Mlme.CntlMachine.CurrState = CNTL_IDLE; pAd->Mlme.SyncMachine.CurrState = SYNC_IDLE; DBGPRINT(RT_DEBUG_TRACE, ("Cancel Scan Timer\n")); } NdisMoveMemory(&PeerConfigMethod, pElem->Msg, pElem->MsgLen); if (pAd->StaCfg.IWscInfo.bLimitedUI) { if (PeerConfigMethod & WPS_CONFIG_METHODS_KEYPAD) { if (pIWscInfo->bSinglePIN == FALSE) { pWscCtrl->WscEnrolleePinCode = WscRandomGeneratePinCode(pAd, BSS0); pWscCtrl->WscEnrolleePinCodeLen = 8; pWscCtrl->WscPinCodeLen = 8; DBGPRINT(RT_DEBUG_TRACE, ("IWSC_PeerProbeResponse:: WscPinCode = %d\n", pWscCtrl->WscPinCode)); pWscCtrl->WscStatus = STATUS_WSC_IBSS_NEW_RANDOM_PIN; } else pWscCtrl->WscStatus = STATUS_WSC_IBSS_FIXED_PIN; WscGetRegDataPIN(pAd, pWscCtrl->WscEnrolleePinCode, pWscCtrl); pAd->Mlme.IWscMachine.CurrState = IWSC_START; pAd->StaCfg.IWscInfo.bSendEapolStart = TRUE; } else { DBGPRINT(RT_DEBUG_ERROR, ("IWSC_PeerProbeRequest:: Both devices are limited UI. Shall we change to use PBC mode?\n")); IWSC_Stop(pAd, FALSE); return; } } else { DBGPRINT(RT_DEBUG_TRACE, ("IWSC_PeerProbeResponse:: Please input Peer's PIN\n")); pAd->Mlme.IWscMachine.CurrState = IWSC_WAIT_PIN; pWscCtrl->WscStatus = STATUS_WSC_WAIT_PIN_CODE; } MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID, sizeof(NDIS_802_11_SSID), (VOID *)&pWscCtrl->WscSsid, 0); RTMP_MLME_HANDLER(pAd); DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_PeerProbeResponse\n")); return; } VOID IWSC_PeerPIN( IN PRTMP_ADAPTER pAd, IN PMLME_QUEUE_ELEM pElem) { PWSC_CTRL pWscCtrl = &pAd->StaCfg.WscControl; DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_PeerPIN\n")); if (ADHOC_ON(pAd)) { NdisZeroMemory(pWscCtrl->EntryAddr, MAC_ADDR_LEN); NdisMoveMemory(pWscCtrl->EntryAddr, pWscCtrl->WscPeerMAC, MAC_ADDR_LEN); pWscCtrl->WscState = WSC_STATE_LINK_UP; pWscCtrl->WscStatus = STATUS_WSC_LINK_UP; WscSendEapolStart(pAd, pWscCtrl->WscPeerMAC, STA_MODE); } else { hex_dump("WscPeerMAC", pWscCtrl->WscPeerMAC, MAC_ADDR_LEN); MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID, sizeof(NDIS_802_11_SSID), (VOID *)&pWscCtrl->WscSsid, 0); RTMP_MLME_HANDLER(pAd); pAd->StaCfg.IWscInfo.bSendEapolStart = TRUE; } pAd->Mlme.IWscMachine.CurrState = IWSC_START; DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_PeerPIN\n")); } BOOLEAN IWSC_PeerEapolStart( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry) { PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; BOOLEAN Cancelled; if (pWpsCtrl->WscConfMode != WSC_REGISTRAR) { DBGPRINT(RT_DEBUG_TRACE, ("IWSC_PeerEapolStart:: Not Registrar now(WscConfMode = %d)\n", pWpsCtrl->WscConfMode)); return FALSE; } DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_PeerEapolStart\n")); // Receive enrollee identity from EAP if (pWpsCtrl->WscMode == WSC_PBC_MODE) { /* Some WPS PBC Station select AP from UI directly; doesn't do PBC scan. Need to check DPID from STA again here. */ WscPBC_DPID_FromSTA(pAd, pEntry->Addr); WscPBCSessionOverlapCheck(pAd); if ((pAd->CommonCfg.WscStaPbcProbeInfo.WscPBCStaProbeCount == 1) && !NdisEqualMemory(pAd->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[0], &ZERO_MAC_ADDR[0], MAC_ADDR_LEN) && (NdisEqualMemory(pAd->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[0], &pEntry->Addr[0], 6) == FALSE)) { pAd->CommonCfg.WscPBCOverlap = TRUE; } //if (pAd->CommonCfg.WscPBCOverlap) { hex_dump("EntryAddr", pWpsCtrl->EntryAddr, 6); hex_dump("StaMacAddr0", pAd->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[0], 6); hex_dump("StaMacAddr1", pAd->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[1], 6); hex_dump("StaMacAddr2", pAd->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[2], 6); hex_dump("StaMacAddr3", pAd->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[3], 6); } if (pAd->CommonCfg.WscPBCOverlap == TRUE) { // PBC session overlap pWpsCtrl->WscStatus = STATUS_WSC_PBC_SESSION_OVERLAP; RTMPSendWirelessEvent(pAd, IW_WSC_PBC_SESSION_OVERLAP, NULL, pWpsCtrl->EntryIfIdx, 0); DBGPRINT(RT_DEBUG_TRACE, ("IWSC_PeerEapolStart: PBC Session Overlap!\n")); IWSC_MlmeStopAction(pAd, NULL); return FALSE; } } else if (pWpsCtrl->WscMode == WSC_SMPBC_MODE) { if (pEntry->bIWscSmpbcAccept == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("IWSC_PeerEapolStart:: pEntry->bIWscSmpbcAccept == FALSE\n")); return FALSE; } if (pWpsCtrl->EapMsgRunning == TRUE) { DBGPRINT(RT_DEBUG_TRACE, ("IWSC_PeerEapolStart:: Busy now\n")); return FALSE; } if (pIWscInfo->bIWscT1TimerRunning) { RTMPCancelTimer(&pIWscInfo->IWscT1Timer, &Cancelled); pIWscInfo->bIWscT1TimerRunning = FALSE; } } if (pIWscInfo->bIWscT2TimerRunning) { RTMPCancelTimer(&pIWscInfo->IWscT2Timer, &Cancelled); pIWscInfo->bIWscT2TimerRunning = FALSE; } if (MAC_ADDR_EQUAL(pWpsCtrl->EntryAddr, ZERO_MAC_ADDR)) { NdisMoveMemory(pWpsCtrl->EntryAddr, pEntry->Addr, MAC_ADDR_LEN); } DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_PeerEapolStart\n")); return TRUE; } VOID IWSC_RoleAction( IN PRTMP_ADAPTER pAd, IN INT WscConfMode) { PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; USHORT WscMode; USHORT ConfigMethod = pWpsCtrl->WscConfigMethods; if (WscConfMode == WSC_REGISTRAR) { pWpsCtrl->WscConfMode = WSC_REGISTRAR; AsicDisableSync(pAd); if (pWpsCtrl->WscMode == WSC_PBC_MODE) WscMode = DEV_PASS_ID_PBC; else if (pWpsCtrl->WscMode == WSC_SMPBC_MODE) WscMode = DEV_PASS_ID_SMPBC; else { WscMode = DEV_PASS_ID_REG; } if (!pAd->StaCfg.IWscInfo.bLimitedUI) ConfigMethod |= WPS_CONFIG_METHODS_KEYPAD; else ConfigMethod &= (~WPS_CONFIG_METHODS_KEYPAD); WscBuildBeaconIE(pAd, pWpsCtrl->WscConfStatus, TRUE, WscMode, ConfigMethod, BSS0, NULL, 0, STA_MODE); WscBuildProbeRespIE(pAd, WSC_MSGTYPE_REGISTRAR, pWpsCtrl->WscConfStatus, TRUE, WscMode, ConfigMethod, BSS0, NULL, 0, STA_MODE); MakeIbssBeacon(pAd); /* re-build BEACON frame */ AsicEnableIbssSync(pAd); /* copy BEACON frame to on-chip memory */ pWpsCtrl->WscState = WSC_STATE_LINK_UP; pWpsCtrl->WscStatus = STATUS_WSC_LINK_UP; RTMPSendWirelessEvent(pAd, IW_IWSC_BECOME_REGISTRAR, NULL, pWpsCtrl->EntryIfIdx, 0); } else { pWpsCtrl->WscRejectSamePinFromEnrollee = FALSE; pWpsCtrl->WscConfMode = WSC_ENROLLEE; /* Set the AutoReconnectSsid to prevent it reconnect to old SSID */ pAd->MlmeAux.AutoReconnectSsidLen= 32; NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->MlmeAux.AutoReconnectSsidLen); AsicDisableSync(pAd); pAd->StaCfg.WpsIEBeacon.ValueLen = 0; pAd->StaCfg.WpsIEProbeResp.ValueLen = 0; MakeIbssBeacon(pAd); /* re-build BEACON frame */ AsicEnableIbssSync(pAd); /* copy BEACON frame to on-chip memory */ pWpsCtrl->WscState = WSC_STATE_START; pWpsCtrl->WscStatus = STATUS_WSC_SCAN_AP; NdisZeroMemory(&pWpsCtrl->WscSsid, sizeof(NDIS_802_11_SSID)); RTMPSendWirelessEvent(pAd, IW_IWSC_BECOME_ENROLLEE, NULL, pWpsCtrl->EntryIfIdx, 0); // For PBC, the PIN is all '0' WscGetRegDataPIN(pAd, pWpsCtrl->WscPinCode, pWpsCtrl); WscScanExec(pAd, pWpsCtrl); } } VOID IWSC_AddSmpbcEnrollee( IN PRTMP_ADAPTER pAd, IN PUCHAR pPeerAddr) { PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; PMAC_TABLE_ENTRY pEntry = NULL; PWSC_PEER_ENTRY pWscPeerEntry = NULL; DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_AddSmpbcEnrollee (WscConfMode = %d, WscStatus = %d)\n", pWpsCtrl->WscConfMode, pWpsCtrl->WscStatus)); pWscPeerEntry = WscFindPeerEntry(&pWpsCtrl->WscPeerList, pPeerAddr); if (pWscPeerEntry && pWscPeerEntry->bIWscSmpbcAccept && !pIWscInfo->bIWscEntryTimerRunning) { pEntry = MacTableLookup(pAd, pPeerAddr); if (pEntry == NULL) pEntry = MacTableInsertEntry(pAd, pPeerAddr, BSS0, OPMODE_STA, FALSE); if (pEntry) { pEntry->bIWscSmpbcAccept = TRUE; if ((pWpsCtrl->WscConfMode == WSC_DISABLE) && (pWpsCtrl->WscStatus == STATUS_WSC_CONFIGURED || pWpsCtrl->WscStatus == STATUS_WSC_IBSS_WAIT_NEXT_SMPBC_ENROLLEE)) { pWpsCtrl->WscConfMode = WSC_REGISTRAR; pWpsCtrl->WscMode = WSC_SMPBC_MODE; pWpsCtrl->WscState = WSC_STATE_LINK_UP; pWpsCtrl->WscStatus = STATUS_WSC_LINK_UP; pWpsCtrl->bWscTrigger = TRUE; WscBuildProbeRespIE(pAd, WSC_MSGTYPE_REGISTRAR, pAd->StaCfg.WscControl.WscConfStatus, TRUE, DEV_PASS_ID_SMPBC, pAd->StaCfg.WscControl.WscConfigMethods, BSS0, NULL, 0, STA_MODE); } DBGPRINT(RT_DEBUG_TRACE, ("SMPBC Enrollee - %02x:%02x:%02x:%02x:%02x:%02x\n", pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5])); } } else if (pIWscInfo->bIWscEntryTimerRunning) { pEntry = MacTableLookup(pAd, pPeerAddr); if (pEntry == NULL) { pEntry = MacTableInsertEntry(pAd, pPeerAddr, BSS0, OPMODE_STA, FALSE); pWscPeerEntry = WscFindPeerEntry(&pWpsCtrl->WscPeerList, pPeerAddr); if (pWscPeerEntry == NULL) pIWscInfo->IWscSmpbcAcceptCount++; } if (pEntry && !pEntry->bIWscSmpbcAccept) { pEntry->bIWscSmpbcAccept = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("Accept this peer enrollee - %02x:%02x:%02x:%02x:%02x:%02x\n", pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5])); WscInsertPeerEntryByMAC(&pWpsCtrl->WscPeerList, pPeerAddr); pWscPeerEntry = WscFindPeerEntry(&pWpsCtrl->WscPeerList, pPeerAddr); if (pWscPeerEntry) pWscPeerEntry->bIWscSmpbcAccept = TRUE; if ((pWpsCtrl->WscConfMode == WSC_DISABLE) && (pWpsCtrl->WscStatus == STATUS_WSC_CONFIGURED || pWpsCtrl->WscStatus == STATUS_WSC_IBSS_WAIT_NEXT_SMPBC_ENROLLEE)) { pWpsCtrl->WscConfMode = WSC_REGISTRAR; pWpsCtrl->WscMode = WSC_SMPBC_MODE; pWpsCtrl->WscState = WSC_STATE_LINK_UP; pWpsCtrl->WscStatus = STATUS_WSC_LINK_UP; pWpsCtrl->bWscTrigger = TRUE; } WscBuildProbeRespIE(pAd, WSC_MSGTYPE_REGISTRAR, pAd->StaCfg.WscControl.WscConfStatus, TRUE, DEV_PASS_ID_SMPBC, pAd->StaCfg.WscControl.WscConfigMethods, BSS0, NULL, 0, STA_MODE); } } DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_AddSmpbcEnrollee\n")); return; } ULONG IWSC_SearchWpsApByPinMethod( IN PRTMP_ADAPTER pAd) { UCHAR i; BSS_ENTRY *pBss; for (i = 0; i < pAd->ScanTab.BssNr; i++) { pBss = &pAd->ScanTab.BssEntry[i]; if ((pBss->WpsAP) && (pBss->BssType == BSS_ADHOC) && ((pBss->WscDPIDFromWpsAP == DEV_PASS_ID_PIN) || (pBss->WscDPIDFromWpsAP == DEV_PASS_ID_REG))) { return (ULONG)i; } } return (ULONG)BSS_NOT_FOUND; } VOID IWSC_GetConfigMethod( IN PRTMP_ADAPTER pAd, IN PUCHAR pVIE, IN INT VIELen, OUT PUSHORT pConfigMethod) { PUCHAR pData = pVIE; INT Len = VIELen; PBEACON_EID_STRUCT pEid; USHORT Type = 0, TLV_Len = 0; while (Len > 0) { pEid = (PBEACON_EID_STRUCT) pData; // No match, skip the Eid and move forward, IE_WFA_WSC = 0xdd if (pEid->Eid != IE_WFA_WSC) { // Set the offset and look for next IE pData += (pEid->Len + 2); Len -= (pEid->Len + 2); continue; } else { // Found IE with 0xdd // check for WSC OUI -- 00 50 f2 04 if (NdisEqualMemory(pEid->Octet, IWSC_OUI, 4) == FALSE) { // Set the offset and look for next IE pData += (pEid->Len + 2); Len -= (pEid->Len + 2); continue; } } // 3. Found AP with WSC IE in beacons, skip 6 bytes = 1 + 1 + 4 pData += 6; Len -= 6; // 4. Start to look the PBC type within WSC VarIE while (Len > 0) { // Check for WSC IEs NdisMoveMemory(&Type, pData, 2); NdisMoveMemory(&TLV_Len, pData+2, 2); // Check for config method if (be2cpu16(Type) == WSC_ID_SEL_REG_CFG_METHODS) { NdisMoveMemory(pConfigMethod, pData+4, 2); *pConfigMethod = be2cpu16(*pConfigMethod); } // Set the offset and look for PBC information // Since Type and Length are both short type, we need to offset 4, not 2 pData += (be2cpu16(TLV_Len) + 4); Len -= (be2cpu16(TLV_Len) + 4); } } } VOID IWSC_BuildDevQueryFrame( IN PRTMP_ADAPTER pAd, OUT PUCHAR pOutBuf, OUT PUSHORT pIeLen) { UCHAR *Data = NULL; PUCHAR pData; INT Len = 0, templen = 0; PWSC_CTRL pWpsCtrl = &pAd->StaCfg.WscControl; PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWpsCtrl->RegData; USHORT tempVal = 0; WSC_IE_HEADER ieHdr; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&Data, 512); if (Data == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } DBGPRINT(RT_DEBUG_TRACE, ("-----> IWSC_BuildDevQueryFrame\n")); // WSC IE HEader ieHdr.elemId = 221; ieHdr.length = 4; ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50; ieHdr.oui[2] = 0xF2; ieHdr.oui[3] = 0x10; pData = (PUCHAR) &Data[0]; Len = 0; /* Version */ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0); pData += templen; Len += templen; /* MAC address */ templen = AppendWSCTLV(WSC_ID_MAC_ADDR, pData, pReg->SelfInfo.MacAddr, 0); pData += templen; Len += templen; /* Manufacture */ templen = AppendWSCTLV(WSC_ID_MANUFACTURER, pData, pReg->SelfInfo.Manufacturer, strlen((PSTRING) pReg->SelfInfo.Manufacturer)); pData += templen; Len += templen; /* Model Name */ templen = AppendWSCTLV(WSC_ID_MODEL_NAME, pData, pReg->SelfInfo.ModelName, strlen((PSTRING) pReg->SelfInfo.ModelName)); pData += templen; Len += templen; /* Model Number */ templen = AppendWSCTLV(WSC_ID_MODEL_NUMBER, pData, pReg->SelfInfo.ModelNumber, strlen((PSTRING) pReg->SelfInfo.ModelNumber)); pData += templen; Len += templen; /* Device Name */ templen = AppendWSCTLV(WSC_ID_DEVICE_NAME, pData, pReg->SelfInfo.DeviceName, strlen((PSTRING) pReg->SelfInfo.DeviceName)); pData += templen; Len += templen; ieHdr.length = ieHdr.length + Len; RTMPMoveMemory(pOutBuf, &ieHdr, sizeof(WSC_IE_HEADER)); RTMPMoveMemory(pOutBuf + sizeof(WSC_IE_HEADER), Data, Len); *pIeLen = (USHORT)(sizeof(WSC_IE_HEADER) + Len); if (Data != NULL) os_free_mem(NULL, Data); DBGPRINT(RT_DEBUG_TRACE, ("<----- IWSC_BuildDevQueryFrame\n")); } VOID IWSC_ResetIpContent( IN PRTMP_ADAPTER pAd) { PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; DBGPRINT(RT_DEBUG_TRACE, ("<----- %s\n", __FUNCTION__)); pIWscInfo->IpDevCount = 0; pIWscInfo->RegDepth = 0; pIWscInfo->AvaSubMaskListCount = IWSC_MAX_SUB_MASK_LIST_COUNT; pIWscInfo->bAssignWscIPv4 = TRUE; pIWscInfo->AvaSubMaskList[0] = IWSC_IPV4_RANGE1; pIWscInfo->AvaSubMaskList[1] = IWSC_IPV4_RANGE2; pIWscInfo->AvaSubMaskList[2] = IWSC_IPV4_RANGE3; DBGPRINT(RT_DEBUG_TRACE, ("<----- %s\n", __FUNCTION__)); } BOOLEAN IWSC_IpContentForCredential( IN PRTMP_ADAPTER pAd) { PIWSC_INFO pIWscInfo = &pAd->StaCfg.IWscInfo; if (pIWscInfo->IpDevCount >= IWSC_MAX_IP_DEV_COUNT) { DBGPRINT(RT_DEBUG_TRACE, ("pIWscInfo->IpDevCount = %d\n", pIWscInfo->IpDevCount)); return FALSE; } if (pIWscInfo->bAssignWscIPv4 == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("pIWscInfo->bAssignWscIPv4 = %d\n", pIWscInfo->bAssignWscIPv4)); return FALSE; } if (pIWscInfo->RegDepth == 0) { pIWscInfo->IpDevCount++; pIWscInfo->SelfIpv4Addr = IWSC_DEFAULT_REG_IPV4_ADDR; pIWscInfo->PeerIpv4Addr = pIWscInfo->SelfIpv4Addr + pIWscInfo->IpDevCount; DBGPRINT(RT_DEBUG_TRACE, ("1) SelfIpv4Addr = 0x%08x, PeerIpv4Addr = 0x%08x\n", pIWscInfo->SelfIpv4Addr, pIWscInfo->PeerIpv4Addr)); return TRUE; } else { UINT32 shift_offset = 0; UINT32 dev_count = (UINT32)(++pIWscInfo->IpDevCount); if (pIWscInfo->SelfIpv4Addr == 0) { DBGPRINT(RT_DEBUG_TRACE, ("IMPOSSIBLE!! pIWscInfo->SelfIpv4Addr = %d\n", pIWscInfo->SelfIpv4Addr)); return FALSE; } if (pIWscInfo->CurrentIpRange == IWSC_IPV4_RANGE0) { shift_offset = 0; } else if (pIWscInfo->CurrentIpRange == IWSC_IPV4_RANGE1) { shift_offset = 6; } else if (pIWscInfo->CurrentIpRange == IWSC_IPV4_RANGE2) { shift_offset = 12; } else if (pIWscInfo->CurrentIpRange == IWSC_IPV4_RANGE3) { shift_offset = 18; } pIWscInfo->PeerIpv4Addr = (pIWscInfo->SelfIpv4Addr & pIWscInfo->CurrentIpRange) + (dev_count << shift_offset); DBGPRINT(RT_DEBUG_TRACE, ("2) SelfIpv4Addr = 0x%08x, PeerIpv4Addr = 0x%08x\n", pIWscInfo->SelfIpv4Addr, pIWscInfo->PeerIpv4Addr)); return TRUE; } } #endif /* IWSC_SUPPORT */