/* *************************************************************************** * Ralink Tech Inc. * 4F, No. 2 Technology 5th Rd. * Science-based Industrial Park * Hsin-chu, Taiwan, R.O.C. * * (c) Copyright 2002-2006, 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: wsc.c Abstract: Revision History: Who When What -------- ---------- ---------------------------------------------- Paul Lin 06-08-08 Initial Snowpin Lee 06-09-12 Do modifications and Add APIs for AP Snowpin Lee 07-04-19 Do modifications and Add APIs for STA Snowpin Lee 07-05-17 Do modifications and Add APIs for AP Client */ #include "rt_config.h" #ifdef WSC_INCLUDED #include "wsc_tlv.h" /*#ifdef LINUX */ /*#include */ /*#endif*/ #define WSC_UPNP_MSG_TIMEOUT (150 * OS_HZ) #define RTMP_WSC_NLMSG_SIGNATURE_LEN 8 #define MAX_WEPKEYNAME_LEN 20 #define MAX_WEPKEYTYPE_LEN 20 #ifndef PF_NOFREEZE #define PF_NOFREEZE 0 #endif char WSC_MSG_SIGNATURE[]={"RAWSCMSG"}; extern UCHAR WPS_OUI[]; extern UCHAR RALINK_OUI[]; #ifdef IWSC_SUPPORT extern UCHAR IWSC_OUI[]; #endif // IWSC_SUPPORT // #if defined(__ECOS) && defined(BRANCH_ADV) extern int CFG_set(int id, void *val); extern int CFG_str2id(char * var); extern int CFG_commit(int id); #else #define CFG_set(a, b) {} #define CFG_str2id(a) {} #define CFG_commit(a) {} #endif /*__ECOS && BRANCH_ADV */ UINT8 WPS_DH_G_VALUE[1] = {0x02}; UINT8 WPS_DH_P_VALUE[192] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE4, 0x5B, 0x3D, 0xC2, 0x00, 0x7C, 0xB8, 0xA1, 0x63, 0xBF, 0x05, 0x98, 0xDA, 0x48, 0x36, 0x1C, 0x55, 0xD3, 0x9A, 0x69, 0x16, 0x3F, 0xA8, 0xFD, 0x24, 0xCF, 0x5F, 0x83, 0x65, 0x5D, 0x23, 0xDC, 0xA3, 0xAD, 0x96, 0x1C, 0x62, 0xF3, 0x56, 0x20, 0x85, 0x52, 0xBB, 0x9E, 0xD5, 0x29, 0x07, 0x70, 0x96, 0x96, 0x6D, 0x67, 0x0C, 0x35, 0x4E, 0x4A, 0xBC, 0x98, 0x04, 0xF1, 0x74, 0x6C, 0x08, 0xCA, 0x23, 0x73, 0x27, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, }; /* General used field */ UCHAR STA_Wsc_Pri_Dev_Type[8] = {0x00, 0x01, 0x00, 0x50, 0xf2, 0x04, 0x00, 0x01}; #ifdef CONFIG_AP_SUPPORT UCHAR AP_Wsc_Pri_Dev_Type[8] = {0x00, 0x06, 0x00, 0x50, 0xf2, 0x04, 0x00, 0x01}; VOID WscDelWPARetryTimer( IN PRTMP_ADAPTER pAd); #ifdef APCLI_SUPPORT VOID WscApCliLinkDown( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl); #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ BOOLEAN WscCheckNonce( IN PRTMP_ADAPTER pAdapter, IN MLME_QUEUE_ELEM *Elem, IN BOOLEAN bFlag, IN PWSC_CTRL pWscControl); VOID WscEapActionDisabled( IN PRTMP_ADAPTER pAdapter, IN PWSC_CTRL pWscControl); VOID WscGetConfigErrFromNack( IN PRTMP_ADAPTER pAdapter, IN MLME_QUEUE_ELEM *pElem, OUT USHORT *pConfigError); INT WscSetAuthMode( IN PRTMP_ADAPTER pAd, IN UCHAR CurOpMode, IN UCHAR apidx, IN PSTRING arg); INT WscSetEncrypType( IN PRTMP_ADAPTER pAd, IN UCHAR CurOpMode, IN UCHAR apidx, IN PSTRING arg); VOID WscSendNACK( IN PRTMP_ADAPTER pAdapter, IN MAC_TABLE_ENTRY *pEntry, IN PWSC_CTRL pWscControl); static INT wsc_write_dat_file_thread(IN ULONG data); #ifdef CONFIG_STA_SUPPORT VOID WscLinkDown( IN PRTMP_ADAPTER pAd); #endif /* CONFIG_STA_SUPPORT */ VOID WscDelListEntryByMAC( PLIST_HEADER pWscEnList, IN PUCHAR pMacAddr); NDIS_802_11_AUTHENTICATION_MODE WscGetAuthMode( IN USHORT authFlag); NDIS_802_11_WEP_STATUS WscGetWepStatus( IN USHORT encryFlag); /* Standard UUID generation procedure. The UUID format generated by this function is base on UUID std. version 1. It's a 16 bytes, one-time global unique number. and can show in string format like this: 550e8400-e29b-41d4-a716-446655440000 The format of uuid is: uuid = "-" "-" "-" "-" time_low = 4* time_mid = 2* time_high_and_version = 2* clock_seq_high_and_reserved = clock_seq_low = node = 6* hex_octet = hex_digit = "0"|"1"|"2"|"3"|"4"|"5"|"6"|"7"|"8"|"9" |"a"|"b"|"c"|"d"|"e"|"f" |"A"|"B"|"C"|"D"|"E"|"F" Note: Actually, to IOT with JumpStart, we fix the first 10 bytes of UUID string!!!! */ INT WscGenerateUUID( RTMP_ADAPTER *pAd, UCHAR *uuidHexStr, UCHAR *uuidAscStr, int apIdx, BOOLEAN bUseCurrentTime) { WSC_UUID_T uuid_t; unsigned long long uuid_time; int i; UINT16 clkSeq; char uuidTmpStr[UUID_LEN_STR+2]; /* Get the current time. */ if (bUseCurrentTime) { NdisGetSystemUpTime((ULONG *)&uuid_time); } else uuid_time = 2860; /*xtime.tv_sec; // Well, we fix this to make JumpStart happy! */ uuid_time *= 10000000; uuid_time += 0x01b21dd213814000LL; uuid_t.timeLow = (UINT32)uuid_time & 0xFFFFFFFF; uuid_t.timeMid = (UINT16)((uuid_time >>32) & 0xFFFF); uuid_t.timeHi_Version = (UINT16)((uuid_time >> 48) & 0x0FFF); uuid_t.timeHi_Version |= (1 << 12); /* Get the clock sequence. */ clkSeq = (UINT16)(0x0601/*jiffies*/ & 0xFFFF); /* Again, we fix this to make JumpStart happy! */ uuid_t.clockSeqLow = clkSeq & 0xFF; uuid_t.clockSeqHi_Var = (clkSeq & 0x3F00) >> 8; uuid_t.clockSeqHi_Var |= 0x80; #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { /* copy the Mac address as the value of node */ NdisMoveMemory(&uuid_t.node[0], &pAd->ApCfg.MBSSID[apIdx].Bssid[0], sizeof(uuid_t.node)); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { #ifdef P2P_SUPPORT /* copy the Mac address as the value of node */ if (apIdx >= MIN_NET_DEVICE_FOR_P2P_GO) NdisMoveMemory(&uuid_t.node[0], &pAd->ApCfg.MBSSID[MAIN_MBSSID].Bssid[0], sizeof(uuid_t.node)); else #endif /* P2P_SUPPORT */ NdisMoveMemory(&uuid_t.node[0], &pAd->CurrentAddress[0], sizeof(uuid_t.node)); } #endif /* CONFIG_STA_SUPPORT */ /* Create the UUID ASCII string. */ memset(uuidTmpStr, 0, sizeof(uuidTmpStr)); snprintf(uuidTmpStr, sizeof(uuidTmpStr), "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", (unsigned int)uuid_t.timeLow, uuid_t.timeMid, uuid_t.timeHi_Version, uuid_t.clockSeqHi_Var, uuid_t.clockSeqLow, uuid_t.node[0], uuid_t.node[1], uuid_t.node[2], uuid_t.node[3], uuid_t.node[4], uuid_t.node[5]); if (strlen(uuidTmpStr) > UUID_LEN_STR) DBGPRINT(RT_DEBUG_ERROR, ("ERROR:UUID String size too large!\n")); strncpy((PSTRING)uuidAscStr, uuidTmpStr, UUID_LEN_STR); /* Create the UUID Hex format number */ uuid_t.timeLow = cpu2be32(uuid_t.timeLow); NdisMoveMemory(&uuidHexStr[0], &uuid_t.timeLow, 4); uuid_t.timeMid = cpu2be16(uuid_t.timeMid); NdisMoveMemory(&uuidHexStr[4], &uuid_t.timeMid, 2); uuid_t.timeHi_Version = cpu2be16(uuid_t.timeHi_Version); NdisMoveMemory(&uuidHexStr[6], &uuid_t.timeHi_Version, 2); NdisMoveMemory(&uuidHexStr[8], &uuid_t.clockSeqHi_Var, 1); NdisMoveMemory(&uuidHexStr[9], &uuid_t.clockSeqLow, 1); NdisMoveMemory(&uuidHexStr[10], &uuid_t.node[0], 6); DBGPRINT(RT_DEBUG_TRACE, ("The UUID Hex string is:")); for (i=0; i< 16; i++) { DBGPRINT(RT_DEBUG_TRACE, ("%02x", (uuidHexStr[i] & 0xff))); } DBGPRINT(RT_DEBUG_TRACE, ("\n")); DBGPRINT(RT_DEBUG_TRACE, ("The UUID ASCII string is:%s!\n", uuidAscStr)); return 0; } VOID WscInitCommonTimers( IN PRTMP_ADAPTER pAdapter, IN PWSC_CTRL pWscControl) { WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->EapolTimer, pWscControl->EapolTimerRunning, WscEAPOLTimeOutAction); WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->Wsc2MinsTimer, pWscControl->Wsc2MinsTimerRunning, Wsc2MinsTimeOutAction); WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->WscUPnPNodeInfo.UPnPMsgTimer, pWscControl->WscUPnPNodeInfo.bUPnPMsgTimerRunning, WscUPnPMsgTimeOutAction); pWscControl->WscUPnPNodeInfo.bUPnPMsgTimerPending = FALSE; WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->M2DTimer, pWscControl->bM2DTimerRunning, WscM2DTimeOutAction); #ifdef WSC_LED_SUPPORT WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->WscLEDTimer, pWscControl->WscLEDTimerRunning, WscLEDTimer); WSC_TIMER_INIT(pAdapter, pWscControl, &pWscControl->WscSkipTurnOffLEDTimer, pWscControl->WscSkipTurnOffLEDTimerRunning, WscSkipTurnOffLEDTimer); #endif /* WSC_LED_SUPPORT */ } VOID WscInitClientTimers( IN PRTMP_ADAPTER pAdapter, IN PWSC_CTRL pWScControl) { WSC_TIMER_INIT(pAdapter, pWScControl, &pWScControl->WscPBCTimer, pWScControl->WscPBCTimerRunning, WscPBCTimeOutAction); WSC_TIMER_INIT(pAdapter, pWScControl, &pWScControl->WscScanTimer, pWScControl->WscScanTimerRunning, WscScanTimeOutAction); WSC_TIMER_INIT(pAdapter, pWScControl, &pWScControl->WscProfileRetryTimer, pWScControl->WscProfileRetryTimerRunning, WscProfileRetryTimeout); /* add by johnli, fix WPS test plan 5.1.1 */ } /* ========================================================================== Description: wps state machine init, including state transition and timer init Parameters: S - pointer to the association state machine ========================================================================== */ VOID WscStateMachineInit( IN PRTMP_ADAPTER pAd, IN STATE_MACHINE *S, OUT STATE_MACHINE_FUNC Trans[]) { PWSC_CTRL pWScControl; StateMachineInit(S, (STATE_MACHINE_FUNC*)Trans, MAX_WSC_STATE, MAX_WSC_MSG, (STATE_MACHINE_FUNC)Drop, WSC_IDLE, WSC_MACHINE_BASE); StateMachineSetAction(S, WSC_IDLE, WSC_EAPOL_START_MSG, (STATE_MACHINE_FUNC)WscEAPOLStartAction); StateMachineSetAction(S, WSC_IDLE, WSC_EAPOL_PACKET_MSG, (STATE_MACHINE_FUNC)WscEAPAction); StateMachineSetAction(S, WSC_IDLE, WSC_EAPOL_UPNP_MSG, (STATE_MACHINE_FUNC)WscEAPAction); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { UCHAR apidx; for (apidx = 0; apidx < MAX_MBSSID_NUM(pAd); apidx++) { pWScControl = &pAd->ApCfg.MBSSID[apidx].WscControl; pWScControl->EntryIfIdx= (MIN_NET_DEVICE_FOR_MBSSID | apidx); WscInitCommonTimers(pAd, pWScControl); pWScControl->WscUpdatePortCfgTimerRunning = FALSE; WSC_TIMER_INIT(pAd, pWScControl, &pWScControl->WscUpdatePortCfgTimer, pWScControl->WscUpdatePortCfgTimerRunning, WscUpdatePortCfgTimeout); #ifdef WSC_V2_SUPPORT WSC_TIMER_INIT(pAd, pWScControl, &pWScControl->WscSetupLockTimer, pWScControl->WscSetupLockTimerRunning, WscSetupLockTimeout); #endif /* WSC_V2_SUPPORT */ } #ifdef APCLI_SUPPORT for (apidx = 0; apidx < MAX_APCLI_NUM; apidx++) { pWScControl = &pAd->ApCfg.ApCliTab[apidx].WscControl; pWScControl->EntryIfIdx= (MIN_NET_DEVICE_FOR_APCLI | apidx); WscInitCommonTimers(pAd, pWScControl); WscInitClientTimers(pAd, pWScControl); } #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { pWScControl = &pAd->StaCfg.WscControl; pWScControl->EntryIfIdx = BSS0; WscInitCommonTimers(pAd, pWScControl); WscInitClientTimers(pAd, pWScControl); #ifdef P2P_SUPPORT pWScControl = &pAd->ApCfg.MBSSID[MAIN_MBSSID].WscControl; pWScControl->EntryIfIdx = MIN_NET_DEVICE_FOR_P2P_GO; WscInitCommonTimers(pAd, pWScControl); pWScControl->WscUpdatePortCfgTimerRunning = FALSE; WSC_TIMER_INIT(pAd, pWScControl, &pWScControl->WscUpdatePortCfgTimer, pWScControl->WscUpdatePortCfgTimerRunning, WscUpdatePortCfgTimeout); pWScControl = &pAd->ApCfg.ApCliTab[MAIN_MBSSID].WscControl; pWScControl->EntryIfIdx = MIN_NET_DEVICE_FOR_P2P_CLI; WscInitCommonTimers(pAd, pWScControl); WscInitClientTimers(pAd, pWScControl); #endif /* P2P_SUPPORT */ } #endif /* CONFIG_STA_SUPPORT */ } void WscM2DTimeOutAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { /* For each state, we didn't care about the retry issue, we just send control message to notify the UPnP deamon that some error happened in STATE MACHINE. */ PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext; PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pWscControl->pAd; WSC_UPNP_NODE_INFO *pWscNodeInfo; #ifdef CONFIG_AP_SUPPORT MAC_TABLE_ENTRY *pEntry = NULL; /* UCHAR apidx = MAIN_MBSSID; */ #endif /* CONFIG_AP_SUPPORT */ BOOLEAN Cancelled; UCHAR CurOpMode = 0xFF; #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) CurOpMode = AP_MODE; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) pEntry = MacTableLookup(pAd, pWscControl->EntryAddr); #endif /* CONFIG_AP_SUPPORT */ pWscNodeInfo = &pWscControl->WscUPnPNodeInfo; DBGPRINT(RT_DEBUG_TRACE, ("UPnP StateMachine TimeOut(State=%d!)\n", pWscControl->WscState)); if( #ifdef CONFIG_AP_SUPPORT (((pEntry == NULL) || (pWscNodeInfo->registrarID != 0)) && (CurOpMode == AP_MODE)) || #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT ((pWscNodeInfo->registrarID != 0) && (CurOpMode == STA_MODE)) || #endif /* CONFIG_STA_SUPPORT */ (0)) { DBGPRINT(RT_DEBUG_TRACE, ("%s():pEntry maybe gone or already received M2 Packet!\n", __FUNCTION__)); goto done; } if (pWscControl->M2DACKBalance != 0) { DBGPRINT(RT_DEBUG_TRACE, ("%s(): waiting for M2DACK balance, extend the time!\n", __FUNCTION__)); /* Waiting for M2DACK balance. */ RTMPModTimer(&pWscControl->M2DTimer, WSC_EAP_ID_TIME_OUT); pWscControl->M2DACKBalance = 0; goto done; } else { RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); pWscControl->EapolTimerRunning = FALSE; #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { DBGPRINT(RT_DEBUG_TRACE, ("%s(): send EAP-Fail to wireless Station!\n", __FUNCTION__)); /* Send EAPFail to Wireless Station and reset the status of Wsc. */ WscSendEapFail(pAd, pWscControl, TRUE); /*pEntry->bWscCapable = FALSE; */ if (pEntry != NULL) pEntry->Receive_EapolStart_EapRspId = 0; } #endif /* CONFIG_AP_SUPPORT */ pWscControl->EapMsgRunning = FALSE; pWscControl->WscState = WSC_STATE_OFF; } done: pWscControl->bM2DTimerRunning = FALSE; pWscControl->M2DACKBalance = 0; pWscNodeInfo->registrarID = 0; } VOID WscUPnPMsgTimeOutAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext; PRTMP_ADAPTER pAd; WSC_UPNP_NODE_INFO *pWscNodeInfo; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscUPnPMsgTimeOutAction\n")); /*It shouldn't happened! */ if (!pWscControl) return; pAd = (PRTMP_ADAPTER)pWscControl->pAd; pWscNodeInfo = &pWscControl->WscUPnPNodeInfo; DBGPRINT(RT_DEBUG_TRACE, ("UPnP StateMachine TimeOut(State=%d!)\n", pWscControl->WscState)); if (pWscNodeInfo->bUPnPMsgTimerPending) { #define WSC_UPNP_TIMER_PENDIND_WAIT 2000 RTMPModTimer(&pWscNodeInfo->UPnPMsgTimer, WSC_UPNP_TIMER_PENDIND_WAIT); DBGPRINT(RT_DEBUG_TRACE, ("UPnPMsgTimer Pending......\n")); } else { int dataLen; UCHAR *pWscData; os_alloc_mem(NULL, (UCHAR **)&pWscData, WSC_MAX_DATA_LEN); /* if( (pWscData = kmalloc(WSC_MAX_DATA_LEN, GFP_ATOMIC)) != NULL) */ if (pWscData != NULL) { memset(pWscData, 0, WSC_MAX_DATA_LEN); dataLen = BuildMessageNACK(pAd, pWscControl, pWscData); WscSendUPnPMessage(pAd, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_NORMAL, pWscData, dataLen, 0, 0, &pAd->CurrentAddress[0], AP_MODE); /* kfree(pWscData); */ os_free_mem(NULL, pWscData); } pWscNodeInfo->bUPnPInProgress = FALSE; pWscNodeInfo->bUPnPMsgTimerPending = FALSE; pWscNodeInfo->bUPnPMsgTimerRunning = FALSE; pWscControl->WscState = WSC_STATE_OFF; pWscControl->WscStatus = STATUS_WSC_FAIL; RTMPSendWirelessEvent(pAd, IW_WSC_STATUS_FAIL, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } DBGPRINT(RT_DEBUG_TRACE, ("<----- WscUPnPMsgTimeOutAction\n")); } /* ========================================================================== Description: This function processes EapolStart packets from wps stations or enqueued by self. Return: None ========================================================================== */ VOID WscEAPOLStartAction( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { MAC_TABLE_ENTRY *pEntry; PWSC_CTRL pWpsCtrl = NULL; PHEADER_802_11 pHeader; PWSC_PEER_ENTRY pWscPeer = NULL; UCHAR CurOpMode = 0xFF; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscEAPOLStartAction\n")); pHeader = (PHEADER_802_11)Elem->Msg; pEntry = MacTableLookup(pAd, pHeader->Addr2); /* Cannot find this wps station in MacTable of WPS AP. */ if (pEntry == NULL) { DBGPRINT(RT_DEBUG_TRACE, ("pEntry is NULL.\n")); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLStartAction\n")); return; } #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) CurOpMode = AP_MODE; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (Elem->OpMode != OPMODE_STA) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) pWpsCtrl = &pAd->ApCfg.MBSSID[pEntry->apidx].WscControl; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { #ifdef IWSC_SUPPORT if ((pAd->StaCfg.BssType == BSS_ADHOC) && (IWSC_PeerEapolStart(pAd, pEntry) == FALSE)) { DBGPRINT(RT_DEBUG_TRACE, ("Rejected by IWSC SM. Ignore EAPOL-Start.\n")); return; } #endif // IWSC_SUPPORT // pWpsCtrl = &pAd->StaCfg.WscControl; } #endif /* CONFIG_STA_SUPPORT */ if (pWpsCtrl == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: pWpsCtrl == NULL!\n", __FUNCTION__)); return; } RTMP_SEM_LOCK(&pWpsCtrl->WscPeerListSemLock); WscInsertPeerEntryByMAC(&pWpsCtrl->WscPeerList, pEntry->Addr); RTMP_SEM_UNLOCK(&pWpsCtrl->WscPeerListSemLock); WscMaintainPeerList(pAd, pWpsCtrl); /* Check this STA is first one or not */ if (pWpsCtrl->WscPeerList.size != 0) { pWscPeer = (PWSC_PEER_ENTRY)pWpsCtrl->WscPeerList.pHead; if (NdisEqualMemory(pEntry->Addr, pWscPeer->mac_addr, MAC_ADDR_LEN) == FALSE) { DBGPRINT(RT_DEBUG_TRACE, ("This is not first WSC peer, ignore this EAPOL_Start!\n")); hex_dump("pEntry->Addr", pEntry->Addr, MAC_ADDR_LEN); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) WscApShowPeerList(pAd, NULL); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) WscStaShowPeerList(pAd, NULL); #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLStartAction\n")); return; } } #ifdef P2P_SUPPORT if (P2P_GO_ON(pAd) && (pWpsCtrl->bWscTrigger == FALSE)) { DBGPRINT(RT_DEBUG_TRACE, ("Ignore this EAPOL_Start!\n")); return; } #endif /* P2P_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("WscState = %d\n", pWpsCtrl->WscState)); if ((pEntry->Receive_EapolStart_EapRspId == 0) || (pWpsCtrl->WscState <= WSC_STATE_WAIT_REQ_ID)) { /* Receive the first EapolStart packet of this wps station. */ pEntry->Receive_EapolStart_EapRspId |= WSC_ENTRY_GET_EAPOL_START; DBGPRINT(RT_DEBUG_TRACE, ("WscEAPOLStartAction - receive EAPOL-Start from %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])); /* EapolStart packet is sent by station means this station wants to do wps process with AP. */ pWpsCtrl->EapMsgRunning = TRUE; /* Update EntryAddr again */ NdisMoveMemory(pWpsCtrl->EntryAddr, pEntry->Addr, MAC_ADDR_LEN); if (pEntry->bWscCapable == FALSE) pEntry->bWscCapable = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("WscEAPOLStartAction(ra%d) - send EAP-Req(Id) to %02x:%02x:%02x:%02x:%02x:%02x\n", pEntry->apidx, pEntry->Addr[0], pEntry->Addr[1], pEntry->Addr[2], pEntry->Addr[3], pEntry->Addr[4], pEntry->Addr[5])); /* Send EAP-Request/Id to station */ WscSendEapReqId(pAd, pEntry, CurOpMode); if (!pWpsCtrl->EapolTimerRunning) { pWpsCtrl->EapolTimerRunning = TRUE; /* Set WPS_EAP Messages timeout function. */ RTMPSetTimer(&pWpsCtrl->EapolTimer, WSC_EAP_ID_TIME_OUT); } } else DBGPRINT(RT_DEBUG_TRACE, ("Ignore EAPOL-Start.\n")); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLStartAction\n")); } /* ========================================================================== Description: This is state machine function when receiving EAP packets which is WPS Registration Protocol. There are two roles at our AP, as an 1. Enrollee 2. Internal Registrar 3. Proxy There are two roles at our Station, as an 1. Enrollee 2. External Registrar Running Scenarios: ----------------------------------------------------------------- 1a. Adding an AP as an Enrollee to a station as an External Registrar (EAP) [External Registrar]<----EAP--->[Enrollee_AP] ----------------------------------------------------------------- 2a. Adding a station as an Enrollee to an AP with built-in Registrar (EAP) [Registrar_AP]<----EAP--->[Enrollee_STA] ----------------------------------------------------------------- 3a. Adding an Enrollee with External Registrar (UPnP/EAP) [External Registrar]<----UPnP--->[Proxy_AP]<---EAP--->[Enrollee_STA] ----------------------------------------------------------------- Return: None ========================================================================== */ VOID WscEAPAction( IN PRTMP_ADAPTER pAdapter, IN MLME_QUEUE_ELEM *Elem) { UCHAR MsgType; BOOLEAN bUPnPMsg, Cancelled; MAC_TABLE_ENTRY *pEntry = NULL; UCHAR MacAddr[MAC_ADDR_LEN] = {0}; #ifdef CONFIG_AP_SUPPORT UCHAR apidx = MAIN_MBSSID; #endif /* CONFIG_AP_SUPPORT */ PWSC_CTRL pWscControl = NULL; PWSC_UPNP_NODE_INFO pWscUPnPNodeInfo = NULL; UCHAR CurOpMode = 0xFF; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscEAPAction\n")); /* The first 6 bytes in Elem->Msg is the MAC address of wps peer. */ memmove(MacAddr, Elem->Msg, MAC_ADDR_LEN); memmove(Elem->Msg, Elem->Msg+6, Elem->MsgLen); #ifdef DBG hex_dump("(WscEAPAction)Elem->MsgLen", Elem->Msg, Elem->MsgLen); #endif /* DBG */ MsgType = WscRxMsgType(pAdapter, Elem); bUPnPMsg = Elem->MsgType == WSC_EAPOL_UPNP_MSG ? TRUE : FALSE; DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: Addr: %02x:%02x:%02x:%02x:%02x:%02x, MsgType: 0x%02X, bUPnPMsg: %s\n", PRINT_MAC(MacAddr), MsgType, bUPnPMsg ? "TRUE" : "FALSE")); if (!bUPnPMsg) pEntry = MacTableLookup(pAdapter, MacAddr); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter) CurOpMode = AP_MODE; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAdapter) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (Elem->OpMode != OPMODE_STA) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (!bUPnPMsg) { if (pEntry) { if (IS_ENTRY_CLIENT(pEntry) && pEntry->apidx >= pAdapter->ApCfg.BssidNum) { DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: Unknow apidex(=%d).\n", pEntry->apidx)); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPAction\n")); return; } else { apidx = pEntry->apidx; DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: apidex=%d.\n", pEntry->apidx)); } } else { DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: pEntry is NULL.\n")); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPAction\n")); return; } #ifdef APCLI_SUPPORT /* for ap-client packets */ if (pEntry && IS_ENTRY_APCLI(pEntry)) pWscControl = &pAdapter->ApCfg.ApCliTab[apidx].WscControl; else #endif /* APCLI_SUPPORT */ pWscControl = &pAdapter->ApCfg.MBSSID[apidx].WscControl; } else { int i; for (i = 0 ; i < MAX_MBSSID_NUM(pAdapter); i++) { if(NdisEqualMemory(pAdapter->ApCfg.MBSSID[i].Bssid, MacAddr, MAC_ADDR_LEN)) { apidx = i; break; } } pWscControl = &pAdapter->ApCfg.MBSSID[apidx].WscControl; pWscUPnPNodeInfo = &pAdapter->ApCfg.MBSSID[apidx].WscControl.WscUPnPNodeInfo; pWscUPnPNodeInfo->bUPnPMsgTimerPending = TRUE; } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pWscControl = &pAdapter->StaCfg.WscControl; pWscUPnPNodeInfo = &pWscControl->WscUPnPNodeInfo; pWscUPnPNodeInfo->bUPnPMsgTimerPending = TRUE; } #endif /* CONFIG_STA_SUPPORT */ if (pWscControl == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: pWscControl == NULL!\n", __FUNCTION__)); return; } if (pEntry && IS_ENTRY_CLIENT(pEntry)) { if ((MsgType == WSC_MSG_EAP_REG_RSP_ID) || (MsgType == WSC_MSG_EAP_ENR_RSP_ID)) { if (((pEntry->Receive_EapolStart_EapRspId & WSC_ENTRY_GET_EAP_RSP_ID) == WSC_ENTRY_GET_EAP_RSP_ID) && (pWscControl->WscState > WSC_STATE_WAIT_M1)) { DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: Already receive EAP_RSP(Identitry) from this STA, ignore it.\n")); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPAction\n")); return; } else pEntry->Receive_EapolStart_EapRspId |= WSC_ENTRY_GET_EAP_RSP_ID; } } pWscControl->EapolTimerPending = TRUE; #ifdef WSC_V2_SUPPORT if (MsgType == WSC_MSG_EAP_FRAG_ACK) { WscSendEapFragData(pAdapter, pWscControl, pEntry); return; } else #endif /* WSC_V2_SUPPORT */ if (MsgType == WSC_MSG_EAP_REG_RSP_ID) { /* Receive EAP-Response/Id from external registrar, so the role of AP is enrollee. */ if (((pWscControl->WscConfMode & WSC_ENROLLEE) != 0) || (((pWscControl->WscConfMode & WSC_PROXY) != 0) && bUPnPMsg)) { pWscControl->WscActionMode= WSC_ENROLLEE; pWscControl->WscUseUPnP = bUPnPMsg ? 1 : 0; MsgType = WSC_MSG_EAP_RSP_ID; WscEapEnrolleeAction(pAdapter, Elem, WSC_MSG_EAP_RSP_ID, pEntry, pWscControl); } } else if (MsgType == WSC_MSG_EAP_ENR_RSP_ID) { /* Receive EAP-Response/Id from wps enrollee station, so the role of AP is Registrar or Proxy. */ DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: Rx Identity\n")); pWscControl->WscActionMode = WSC_REGISTRAR; if (bUPnPMsg) { /* Receive enrollee identity from UPnP */ } else { #ifdef CONFIG_AP_SUPPORT /* Receive enrollee identity from EAP */ if ((pWscControl->WscMode == WSC_PBC_MODE) #ifdef P2P_SUPPORT /* P2P doesn't need to check PBC overlapping. */ && (pWscControl->EntryIfIdx < MIN_NET_DEVICE_FOR_P2P_GO) #endif /* P2P_SUPPORT */ ) { /* 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(pAdapter, pWscControl->EntryAddr); WscPBCSessionOverlapCheck(pAdapter); if ((pAdapter->CommonCfg.WscStaPbcProbeInfo.WscPBCStaProbeCount == 1) && !NdisEqualMemory(pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[0], &ZERO_MAC_ADDR[0], MAC_ADDR_LEN) && (NdisEqualMemory(pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[0], &pWscControl->EntryAddr[0], 6) == FALSE)) { pAdapter->CommonCfg.WscPBCOverlap = TRUE; } if (pAdapter->CommonCfg.WscPBCOverlap) { hex_dump("EntryAddr", pWscControl->EntryAddr, 6); hex_dump("StaMacAddr0", pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[0], 6); hex_dump("StaMacAddr1", pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[1], 6); hex_dump("StaMacAddr2", pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[2], 6); hex_dump("StaMacAddr3", pAdapter->CommonCfg.WscStaPbcProbeInfo.StaMacAddr[3], 6); } } if ((pWscControl->WscMode == WSC_PBC_MODE) && (pAdapter->CommonCfg.WscPBCOverlap == TRUE)) { /* PBC session overlap */ pWscControl->WscStatus = STATUS_WSC_PBC_SESSION_OVERLAP; RTMPSendWirelessEvent(pAdapter, IW_WSC_PBC_SESSION_OVERLAP, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); DBGPRINT(RT_DEBUG_TRACE, ("WscEAPAction: PBC Session Overlap!\n")); } else #endif /* CONFIG_AP_SUPPORT */ if ((pWscControl->WscConfMode & WSC_PROXY_REGISTRAR) != 0) { /* Notify UPnP daemon before send Eap-Req(wsc-start) */ DBGPRINT(RT_DEBUG_TRACE, ("%s: pEntry->Addr=%02x:%02x:%02x:%02x:%02x:%02x\n", __FUNCTION__, PRINT_MAC(pEntry->Addr))); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { WscSendUPnPConfReqMsg(pAdapter, (pWscControl->EntryIfIdx & 0x0F), (PUCHAR)pAdapter->ApCfg.MBSSID[pEntry->apidx].Ssid, pEntry->Addr, 2, 0, CurOpMode); /* Reset the UPnP timer and status. */ if (pWscControl->bM2DTimerRunning == TRUE) { RTMPCancelTimer(&pWscControl->M2DTimer, &Cancelled); pWscControl->bM2DTimerRunning = FALSE; } pWscControl->WscUPnPNodeInfo.registrarID = 0; pWscControl->M2DACKBalance = 0; WscDelWPARetryTimer(pAdapter); } #endif /* CONFIG_AP_SUPPORT */ pWscControl->EapMsgRunning = TRUE; /* Change the state to next one */ pWscControl->WscState = WSC_STATE_WAIT_M1; /* send EAP WSC_START */ if (pEntry && IS_ENTRY_CLIENT(pEntry)) { pWscControl->bWscLastOne = TRUE; if (CurOpMode == AP_MODE) WscSendMessage(pAdapter, WSC_OPCODE_START, NULL, 0, pWscControl, AP_MODE, EAP_CODE_REQ); else { if (ADHOC_ON(pAdapter) && (pWscControl->WscConfMode == WSC_REGISTRAR)) WscSendMessage(pAdapter, WSC_OPCODE_START, NULL, 0, pWscControl, STA_MODE, EAP_CODE_REQ); else WscSendMessage(pAdapter, WSC_OPCODE_START, NULL, 0, pWscControl, STA_MODE, EAP_CODE_RSP); } } } } } else if (MsgType == WSC_MSG_EAP_REQ_ID) { /* Receive EAP_Req/Identity from WPS AP or WCN */ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP_Req/Identity from WPS AP or WCN\n")); if (bUPnPMsg && (pWscControl->WscConfMode == WSC_ENROLLEE)) { pWscControl->WscActionMode = WSC_ENROLLEE; pWscControl->WscUseUPnP = 1; WscEapEnrolleeAction(pAdapter, Elem, WSC_MSG_EAP_REQ_START, pEntry, pWscControl); } else { /* Receive EAP_Req/Identity from WPS AP */ if (pEntry != NULL) WscSendEapRspId(pAdapter, pEntry, pWscControl); } if (!bUPnPMsg) { if ((pWscControl->WscState < WSC_STATE_WAIT_M1) || (pWscControl->WscState > WSC_STATE_WAIT_ACK)) { if (pWscControl->WscConfMode == WSC_REGISTRAR) pWscControl->WscState = WSC_STATE_WAIT_M1; else pWscControl->WscState = WSC_STATE_WAIT_WSC_START; } } } else if (MsgType == WSC_MSG_EAP_REQ_START) { DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP_Req(Wsc_Start) from WPS AP\n")); /* Receive EAP_Req(Wsc_Start) from WPS AP */ if (pWscControl->WscConfMode == WSC_ENROLLEE) { pWscControl->WscActionMode = WSC_ENROLLEE; pWscControl->WscUseUPnP = bUPnPMsg ? 1 : 0; WscEapEnrolleeAction(pAdapter, Elem, WSC_MSG_EAP_REQ_START, pEntry, pWscControl); if (!pWscControl->EapolTimerRunning) { pWscControl->EapolTimerRunning = TRUE; RTMPSetTimer(&pWscControl->EapolTimer, WSC_EAP_ID_TIME_OUT); } } else DBGPRINT(RT_DEBUG_TRACE, ("Ignore EAP_Req(Wsc_Start) from WPS AP\n")); } else if (MsgType == WSC_MSG_EAP_FAIL) { /* Receive EAP_Fail from WPS AP */ DBGPRINT(RT_DEBUG_TRACE, ("Receive EAP_Fail from WPS AP\n")); if (pWscControl->WscState >= WSC_STATE_WAIT_EAPFAIL) { pWscControl->WscState = WSC_STATE_OFF; #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (CurOpMode == AP_MODE) { pWscControl->WscConfMode = WSC_DISABLE; #ifdef P2P_SUPPORT if (pWscControl->WscStatus == STATUS_WSC_CONFIGURED) pAdapter->P2pCfg.WscState = WSC_STATE_CONFIGURED; #ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT P2pSendWirelessEvent(pAdapter, RT_P2P_WPS_COMPLETED, NULL, NULL); #endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */ #endif /* P2P_SUPPORT */ /* Bring apcli interface down first */ if(pEntry && IS_ENTRY_APCLI(pEntry) && pAdapter->ApCfg.ApCliTab[BSS0].Enable == TRUE ) { #ifdef P2P_SUPPORT UCHAR P2pIdx = P2pGroupTabSearch(pAdapter, pEntry->Addr); #endif /* P2P_SUPPORT */ pAdapter->ApCfg.ApCliTab[pEntry->apidx].Enable = FALSE; ApCliIfDown(pAdapter); #ifdef P2P_SUPPORT if ((P2pIdx != P2P_NOT_FOUND) && P2P_CLI_ON(pAdapter) && ((pWscControl->WscStatus == STATUS_WSC_ERROR_DEV_PWD_AUTH_FAIL) || (pWscControl->WscStatus == STATUS_WSC_FAIL))) { pAdapter->P2pTable.Client[P2pIdx].P2pClientState = P2PSTATE_DISCOVERY; P2pLinkDown(pAdapter, P2P_CONNECT_FAIL); } #endif /* P2P_SUPPORT */ pAdapter->ApCfg.ApCliTab[pEntry->apidx].Enable = TRUE; } } #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { #ifdef IWSC_SUPPORT if ((pAdapter->OpMode == OPMODE_STA) && (pAdapter->StaCfg.BssType == BSS_ADHOC) && (pAdapter->StaCfg.WscControl.WscConfMode == WSC_ENROLLEE)) pAdapter->StaCfg.IWscInfo.bReStart = TRUE; #endif /* IWSC_SUPPORT */ pWscControl->WscConfMode = WSC_DISABLE; WscLinkDown(pAdapter); } #endif /* CONFIG_STA_SUPPORT */ } else if (pWscControl->WscState == WSC_STATE_RX_M2D) { /* Wait M2; */ #ifdef IWSC_SUPPORT /* We need to send EAPOL_Start again to trigger WPS process */ if (pAdapter->StaCfg.BssType == BSS_ADHOC) { pWscControl->WscState = WSC_STATE_LINK_UP; pWscControl->WscStatus = STATUS_WSC_LINK_UP; WscSendEapolStart(pAdapter, pWscControl->WscPeerMAC, STA_MODE); } #endif /* IWSC_SUPPORT */ } else if ((pWscControl->WscState <= WSC_STATE_WAIT_REQ_ID) && (pWscControl->WscState != WSC_STATE_FAIL)) { /* Ignore. D-Link DIR-628 AP sometimes would send EAP_Fail to station after Link UP first then send EAP_Req/Identity. */ } else { pWscControl->WscStatus = STATUS_WSC_FAIL; RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_FAIL, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); #ifdef IWSC_SUPPORT if ((pAdapter->OpMode == OPMODE_STA) && (pAdapter->StaCfg.BssType == BSS_ADHOC) && (pAdapter->StaCfg.WscControl.WscConfMode == WSC_ENROLLEE)) pAdapter->StaCfg.IWscInfo.bReStart = TRUE; #endif /* IWSC_SUPPORT */ pWscControl->WscConfMode = WSC_DISABLE; /* Change the state to next one */ pWscControl->WscState = WSC_STATE_OFF; #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { WscLinkDown(pAdapter); } #endif /* CONFIG_STA_SUPPORT */ } } else if (MsgType == WSC_MSG_M1) { UINT32 rv = 0; /* If Buffalo WPS STA doesn't receive M2D from AP, Buffalo WPS STA will stop to do WPS. Therefore we need to receive M1 and send M2D without trigger. */ if ((pWscControl->WscConfMode & WSC_REGISTRAR) != 0) { pWscControl->WscActionMode = WSC_REGISTRAR; /* If Message is from EAP, but UPnP Registrar is in progress now, ignore EAP_M1 */ if (!bUPnPMsg && pWscControl->WscUPnPNodeInfo.bUPnPInProgress) { DBGPRINT(RT_DEBUG_TRACE, ("UPnP Registrar is working now, ignore EAP M1.\n")); goto out; } else WscEapRegistrarAction(pAdapter, Elem, MsgType, pEntry, pWscControl); rv = 1; } #ifdef CONFIG_AP_SUPPORT if (((pWscControl->WscConfMode & WSC_PROXY) != 0) && (!bUPnPMsg) && (CurOpMode == AP_MODE)) { if ((pWscControl->bWscTrigger ) && (pWscControl->WscState >= WSC_STATE_WAIT_M3)) ; else { pWscControl->WscActionMode = WSC_PROXY; WscEapApProxyAction(pAdapter, Elem, MsgType, pEntry, pWscControl); } } else if ((!pWscControl->bWscTrigger) && ((pWscControl->WscConfMode & WSC_PROXY) == 0) && (pAdapter->OpMode == OPMODE_AP)) { DBGPRINT(RT_DEBUG_TRACE, ("WscTrigger is FALSE, ignore EAP M1.\n")); goto out; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT else { if ((rv == 0) && (CurOpMode == STA_MODE)) { DBGPRINT(RT_DEBUG_TRACE, ("(Line:%d)Ignore EAP M1.\n", __LINE__)); goto out; } } #endif /* CONFIG_STA_SUPPORT */ } else if (MsgType == WSC_MSG_M3 || MsgType == WSC_MSG_M5 || MsgType == WSC_MSG_M7 || MsgType == WSC_MSG_WSC_DONE) { BOOLEAN bNonceMatch = WscCheckNonce(pAdapter, Elem, TRUE, pWscControl); if (((pWscControl->WscConfMode & WSC_REGISTRAR) != 0) && (pWscControl->bWscTrigger ) && bNonceMatch) { /* If Message is from EAP, but UPnP Registrar is in progress now, ignore EAP Messages */ if (!bUPnPMsg && pWscControl->WscUPnPNodeInfo.bUPnPInProgress) { DBGPRINT(RT_DEBUG_TRACE, ("UPnP Registrar is working now, ignore EAP Messages.\n")); goto out; } else { pWscControl->WscActionMode = WSC_REGISTRAR; WscEapRegistrarAction(pAdapter, Elem, MsgType, pEntry, pWscControl); } } #ifdef CONFIG_AP_SUPPORT else if (((pWscControl->WscConfMode & WSC_PROXY) != 0) && (!bUPnPMsg) && (CurOpMode == AP_MODE)) { pWscControl->WscActionMode = WSC_PROXY; WscEapApProxyAction(pAdapter, Elem, MsgType, pEntry, pWscControl); } #endif /* CONFIG_AP_SUPPORT */ } else if (MsgType == WSC_MSG_M2 || MsgType == WSC_MSG_M2D || MsgType == WSC_MSG_M4 || MsgType == WSC_MSG_M6 || MsgType == WSC_MSG_M8) { BOOLEAN bNonceMatch = WscCheckNonce(pAdapter, Elem, FALSE, pWscControl); BOOLEAN bGoWPS = FALSE; if ((CurOpMode == AP_MODE) || ((CurOpMode == STA_MODE) && (pWscControl->bWscTrigger #ifdef CONFIG_STA_SUPPORT #endif /* CONFIG_STA_SUPPORT */ ))) bGoWPS = TRUE; #ifdef CONFIG_AP_SUPPORT #ifdef WSC_V2_SUPPORT if ((CurOpMode == AP_MODE) && ((pWscControl->WscV2Info.bWpsEnable == FALSE) && (pWscControl->WscV2Info.bEnableWpsV2))) bGoWPS = FALSE; #endif /* WSC_V2_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ if (((pWscControl->WscConfMode & WSC_ENROLLEE) != 0) && bGoWPS && bNonceMatch) { pWscControl->WscActionMode = WSC_ENROLLEE; pWscControl->WscUseUPnP = bUPnPMsg ? 1 : 0; if (MsgType == WSC_MSG_M2) { BOOLEAN bReadOwnPIN = TRUE; #ifdef CONFIG_AP_SUPPORT /* WPS Enrollee AP only supports PIN without trigger */ if (CurOpMode == AP_MODE) { if (pWscControl->bWscTrigger == FALSE) { pWscControl->WscMode = 1; WscGetConfWithoutTrigger(pAdapter, pWscControl, FALSE); } else { WscBuildBeaconIE(pAdapter, pWscControl->WscConfStatus, TRUE, pWscControl->WscMode, pWscControl->WscConfigMethods, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, AP_MODE); WscBuildProbeRespIE(pAdapter, WSC_MSGTYPE_AP_WLAN_MGR, pWscControl->WscConfStatus, TRUE, pWscControl->WscMode, pWscControl->WscConfigMethods, pWscControl->EntryIfIdx, NULL, 0, AP_MODE); APUpdateBeaconFrame(pAdapter, pWscControl->EntryIfIdx & 0x0F); } } #endif /* CONFIG_AP_SUPPORT */ #ifdef P2P_SUPPORT if (P2P_CLI_ON(pAdapter) && (pWscControl->EntryIfIdx != BSS0)) { UCHAR P2pIdx = P2P_NOT_FOUND; P2pIdx = P2pGroupTabSearch(pAdapter, MacAddr); if (P2pIdx != P2P_NOT_FOUND) { PRT_P2P_CLIENT_ENTRY pP2pEntry = &pAdapter->P2pTable.Client[P2pIdx]; if (pP2pEntry && (pAdapter->P2pCfg.ConfigMethod == WSC_CONFMET_KEYPAD)) { /* I am KeyPad. We cannot use ConfigMethod or DPID to check peer's capability. Some P2P device is display but the value of ConfigMethod will be 0x0188 and (ex. Samsung GALAXYSII). */ bReadOwnPIN = FALSE; } } } #endif /* P2P_SUPPORT */ #ifdef IWSC_SUPPORT if (pAdapter->StaCfg.BssType == BSS_ADHOC) bReadOwnPIN = FALSE; #endif /* IWSC_SUPPORT */ if (bReadOwnPIN) { pWscControl->WscPinCodeLen = pWscControl->WscEnrolleePinCodeLen; WscGetRegDataPIN(pAdapter, pWscControl->WscEnrolleePinCode, pWscControl); DBGPRINT(RT_DEBUG_TRACE, ("(%d) WscEnrolleePinCode: %08u\n", bReadOwnPIN, pWscControl->WscEnrolleePinCode)); } else DBGPRINT(RT_DEBUG_TRACE, ("WscPinCode: %08u\n", pWscControl->WscPinCode)); } /* If Message is from EAP, but UPnP Registrar is in progress now, ignore EAP Messages */ if (!bUPnPMsg && pWscControl->WscUPnPNodeInfo.bUPnPInProgress) { DBGPRINT(RT_DEBUG_TRACE, ("UPnP Registrar is working now, ignore EAP Messages.\n")); goto out; } else WscEapEnrolleeAction(pAdapter, Elem, MsgType, pEntry, pWscControl); } #ifdef CONFIG_AP_SUPPORT else if (((pWscControl->WscConfMode & WSC_PROXY) != 0) && (bUPnPMsg) && (CurOpMode == AP_MODE)) { pWscControl->WscActionMode = WSC_PROXY; WscEapApProxyAction(pAdapter, Elem, MsgType, pEntry, pWscControl); } #endif /* CONFIG_AP_SUPPORT */ } else if (MsgType == WSC_MSG_WSC_ACK) { DBGPRINT(RT_DEBUG_TRACE, ("WscState: %d\n", pWscControl->WscState)); if (((pWscControl->WscConfMode & WSC_REGISTRAR) != 0) && pWscControl->WscState <= WSC_STATE_SENT_M2D) { if (WscCheckNonce(pAdapter, Elem, TRUE, pWscControl)) { if (pWscControl->M2DACKBalance > 0) pWscControl->M2DACKBalance--; pWscControl->WscState = WSC_STATE_INIT; pWscControl->EapMsgRunning = FALSE; } } else { if (((pWscControl->WscConfMode & WSC_ENROLLEE) != 0) && WscCheckNonce(pAdapter, Elem, FALSE, pWscControl)) { pWscControl->WscActionMode = WSC_ENROLLEE; pWscControl->WscUseUPnP = bUPnPMsg ? 1 : 0; WscEapEnrolleeAction(pAdapter, Elem, MsgType, pEntry, pWscControl); } #ifdef CONFIG_AP_SUPPORT else if (((pWscControl->WscConfMode & WSC_PROXY) != 0) && (CurOpMode == AP_MODE)) { pWscControl->WscActionMode = WSC_PROXY; WscEapApProxyAction(pAdapter, Elem, MsgType, pEntry, pWscControl); } #endif /* CONFIG_AP_SUPPORT */ } } else if (MsgType == WSC_MSG_WSC_NACK) { BOOLEAN bReSetWscIE = FALSE; if (bUPnPMsg && (pWscControl->WscState == WSC_STATE_WAIT_M8) && (pWscControl->WscConfStatus == WSC_SCSTATE_CONFIGURED)) { // Some external sta will send NACK when AP is configured. // bWscTrigger should be set FALSE, otherwise Proxy will send NACK to enrollee. pWscControl->bWscTrigger = FALSE; pWscControl->WscStatus = STATUS_WSC_CONFIGURED; bReSetWscIE = TRUE; } if (!bUPnPMsg && (WscCheckNonce(pAdapter, Elem, FALSE, pWscControl) || WscCheckNonce(pAdapter, Elem, TRUE, pWscControl))) { USHORT config_error = 0; DBGPRINT(RT_DEBUG_TRACE, ("Receive NACK from WPS client.\n")); WscGetConfigErrFromNack(pAdapter, Elem, &config_error); /* If a PIN authentication or communication error occurs, the Registrar MUST warn the user and MUST NOT automatically reuse the PIN. Furthermore, if the Registrar detects this situation and prompts the user for a new PIN from the Enrollee device, it MUST NOT accept the same PIN again without warning the user of a potential attack. */ if ((pWscControl->WscState >= WSC_STATE_WAIT_M5) && (config_error != WSC_ERROR_SETUP_LOCKED)) { pWscControl->WscRejectSamePinFromEnrollee = TRUE; pWscControl->WscPinCode = 0; if (pWscControl->WscState < WSC_STATE_WAIT_M8) { pWscControl->WscStatus = STATUS_WSC_FAIL; RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_FAIL, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); bReSetWscIE = TRUE; } } #ifdef CONFIG_AP_SUPPORT if ((pWscControl->WscState == WSC_STATE_OFF) && (CurOpMode == AP_MODE) && (pWscControl->RegData.SelfInfo.ConfigError != WSC_ERROR_NO_ERROR)) { bReSetWscIE = TRUE; } #endif /* CONFIG_AP_SUPPORT */ if ((pWscControl->WscState == WSC_STATE_WAIT_M8) && (pWscControl->WscConfStatus == WSC_SCSTATE_CONFIGURED)) { /* Some external sta will send NACK when AP is configured. */ /* bWscTrigger should be set FALSE, otherwise Proxy will send NACK to enrollee. */ pWscControl->bWscTrigger = FALSE; bReSetWscIE = TRUE; pWscControl->WscStatus = STATUS_WSC_CONFIGURED; pWscControl->WscRejectSamePinFromEnrollee = FALSE; RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_SUCCESS, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); #ifdef P2P_SUPPORT /*RTMPCancelTimer(&pAdapter->P2pCfg.P2pWscTimer, &Cancelled);*/ if (P2P_GO_ON(pAdapter) && pWscControl->EntryIfIdx != BSS0) { UCHAR P2pIdx = P2P_NOT_FOUND; P2pIdx = P2pGroupTabSearch(pAdapter, MacAddr); if (P2pIdx != P2P_NOT_FOUND) { PRT_P2P_CLIENT_ENTRY pP2pEntry = &pAdapter->P2pTable.Client[P2pIdx]; // Update p2p Entry's state. pP2pEntry->P2pClientState = P2PSTATE_CLIENT_WPS_DONE; } } // default set extended listening to zero for each connection. If this is persistent, will set it. pAdapter->P2pCfg.ExtListenInterval = 0; pAdapter->P2pCfg.ExtListenPeriod = 0; if (IS_PERSISTENT_ON(pAdapter) && (pEntry->bP2pClient == TRUE)) { UCHAR P2pIdx = P2P_NOT_FOUND; P2pIdx = P2pGroupTabSearch(pAdapter, pEntry->Addr); if (IS_P2P_GO_ENTRY(pEntry)) DBGPRINT(RT_DEBUG_ERROR, ("pEntry is P2P GO.\n")); else if (IS_P2P_CLI_ENTRY(pEntry)) DBGPRINT(RT_DEBUG_ERROR, ("pEntry is P2P CLIENT.\n")); else DBGPRINT(RT_DEBUG_ERROR, ("pEntry is P2P NONE.\n")); if ((P2pIdx != P2P_NOT_FOUND) && (IS_P2P_GO_ENTRY(pEntry) || IS_P2P_CLI_ENTRY(pEntry))) { DBGPRINT(RT_DEBUG_ERROR, ("P2pWPSDone- Save to persistent entry. GrpCap= %x \n", pAdapter->P2pTable.Client[P2pIdx].GroupCapability)); DBGPRINT(RT_DEBUG_ERROR, ("3. P2pWPSDone- Set Extended timing !!!!!!!\n")); DBGPRINT(RT_DEBUG_ERROR, (" ======== Profile :: Cnt = %d ========\n", pWscControl->WscProfile.ProfileCnt)); DBGPRINT(RT_DEBUG_ERROR, (" SSID[%d] = %s.\n", pWscControl->WscProfile.Profile[0].SSID.SsidLength, pWscControl->WscProfile.Profile[0].SSID.Ssid)); DBGPRINT(RT_DEBUG_ERROR, (" AuthType = %d. EncrType = %d.\n", pWscControl->WscProfile.Profile[0].AuthType, pWscControl->WscProfile.Profile[0].EncrType)); DBGPRINT(RT_DEBUG_ERROR, (" MAC = %02x:%02x:%02x:%02x:%02x:%02x.\n", PRINT_MAC(pWscControl->WscProfile.Profile[0].MacAddr))); DBGPRINT(RT_DEBUG_ERROR, (" KeyLen = %d. KeyIdx = %d.\n", pWscControl->WscProfile.Profile[0].KeyLength, pWscControl->WscProfile.Profile[0].KeyIndex)); DBGPRINT(RT_DEBUG_ERROR, (" Key :: %02x %02x %02x %02x %02x %02x %02x %02x\n", pWscControl->WscProfile.Profile[0].Key[0], pWscControl->WscProfile.Profile[0].Key[1], pWscControl->WscProfile.Profile[0].Key[2], pWscControl->WscProfile.Profile[0].Key[3], pWscControl->WscProfile.Profile[0].Key[4], pWscControl->WscProfile.Profile[0].Key[5], pWscControl->WscProfile.Profile[0].Key[6], pWscControl->WscProfile.Profile[0].Key[7])); DBGPRINT(RT_DEBUG_ERROR, (" %02x %02x %02x %02x %02x %02x %02x %02x\n", pWscControl->WscProfile.Profile[0].Key[8], pWscControl->WscProfile.Profile[0].Key[9], pWscControl->WscProfile.Profile[0].Key[10], pWscControl->WscProfile.Profile[0].Key[11], pWscControl->WscProfile.Profile[0].Key[12], pWscControl->WscProfile.Profile[0].Key[13], pWscControl->WscProfile.Profile[0].Key[14], pWscControl->WscProfile.Profile[0].Key[15])); P2pPerstTabInsert(pAdapter, pEntry->Addr, &pWscControl->WscProfile.Profile[0]); // this is a persistent connection. pAdapter->P2pCfg.ExtListenInterval = P2P_EXT_LISTEN_INTERVAL; pAdapter->P2pCfg.ExtListenPeriod = P2P_EXT_LISTEN_PERIOD; } } #endif //P2P_SUPPORT // } #ifdef CONFIG_AP_SUPPORT else if ((CurOpMode == AP_MODE) && (pWscControl->WscState == WSC_STATE_WAIT_DONE) && (pWscControl->WscConfStatus == WSC_SCSTATE_CONFIGURED) && (pAdapter->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled)) { bReSetWscIE = TRUE; pWscControl->WscStatus = STATUS_WSC_FAIL; } if ((CurOpMode == AP_MODE) && bReSetWscIE) { WscBuildBeaconIE(pAdapter, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode); WscBuildProbeRespIE(pAdapter, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, pWscControl->EntryIfIdx, NULL, 0, CurOpMode); APUpdateBeaconFrame(pAdapter, pWscControl->EntryIfIdx & 0x0F); if (pWscControl->Wsc2MinsTimerRunning) { RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled); pWscControl->Wsc2MinsTimerRunning = FALSE; } if (pWscControl->bWscTrigger) pWscControl->bWscTrigger = FALSE; } #endif // CONFIG_AP_SUPPORT // if ((CurOpMode == AP_MODE) || ((ADHOC_ON(pAdapter)) && (pWscControl->WscConfMode == WSC_REGISTRAR)) ) { WscSendEapFail(pAdapter, pWscControl, TRUE); pWscControl->WscState = WSC_STATE_FAIL; } #ifdef CONFIG_STA_SUPPORT else if ((CurOpMode == STA_MODE) && INFRA_ON(pAdapter)) { WscEapActionDisabled(pAdapter, pWscControl); pWscControl->WscState = WSC_STATE_WAIT_DISCONN; } #endif /* CONFIG_STA_SUPPORT */ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); pWscControl->EapolTimerRunning = FALSE; pWscControl->RegData.ReComputePke = 1; } } else { DBGPRINT(RT_DEBUG_TRACE, ("Unsupported Msg Type (%02X)\n", MsgType)); goto out; } if (bUPnPMsg) { /* Messages from UPnP */ if (pWscUPnPNodeInfo->bUPnPMsgTimerRunning) RTMPModTimer(&pWscUPnPNodeInfo->UPnPMsgTimer, WSC_UPNP_MSG_TIME_OUT); } else { if ((pWscControl->EapMsgRunning == TRUE) && (!RTMP_TEST_FLAG(pAdapter, fRTMP_ADAPTER_HALT_IN_PROGRESS | fRTMP_ADAPTER_NIC_NOT_EXIST))) { /* Messages from EAP */ RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); pWscControl->EapolTimerRunning = TRUE; } } if (bUPnPMsg && pWscControl->EapolTimerRunning) { #ifdef CONFIG_AP_SUPPORT if ((pWscControl->WscActionMode == WSC_PROXY) && (CurOpMode == AP_MODE)) { RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } else #endif /* CONFIG_AP_SUPPORT */ { RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); pWscControl->EapolTimerRunning = FALSE; } } out: if (bUPnPMsg) pWscUPnPNodeInfo->bUPnPMsgTimerPending = FALSE; pWscControl->EapolTimerPending = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPAction\n")); } /* ============================================================================ Enrollee Enrollee Enrollee ============================================================================ */ VOID WscEapEnrolleeAction( IN PRTMP_ADAPTER pAdapter, IN MLME_QUEUE_ELEM *Elem, IN UCHAR MsgType, IN MAC_TABLE_ENTRY *pEntry, IN PWSC_CTRL pWscControl) { INT DataLen = 0, rv = 0, DH_Len = 0; UCHAR OpCode, bssIdx; PUCHAR WscData = NULL; BOOLEAN bUPnPMsg, bUPnPStatus = FALSE, Cancelled; WSC_UPNP_NODE_INFO *pWscUPnPInfo = &pWscControl->WscUPnPNodeInfo; UINT MaxWscDataLen = WSC_MAX_DATA_LEN; UCHAR CurOpMode = 0xFF; DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction Enter!\n")); bUPnPMsg = Elem->MsgType == WSC_EAPOL_UPNP_MSG ? TRUE : FALSE; OpCode = bUPnPMsg ? WSC_OPCODE_UPNP_MASK : 0; bssIdx = 0; #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter) CurOpMode = AP_MODE; #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAdapter) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (Elem->OpMode != OPMODE_STA) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { /* Early check. */ if ((pWscControl->WscActionMode != WSC_ENROLLEE) || (pWscControl->WscUseUPnP && pEntry) || ((pWscControl->WscUseUPnP == 0) && (!pEntry))) { DBGPRINT(RT_DEBUG_TRACE, ("EarlyCheckFailed: pWscControl->WscActionMode=%d, Configured=%d, WscUseUPnP=%d, pEntry=%p!\n", pWscControl->WscActionMode, pWscControl->WscConfStatus, pWscControl->WscUseUPnP, pEntry)); goto Fail; } bssIdx = (pWscControl->EntryIfIdx & 0x0F); } #endif /* CONFIG_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("MsgType=0x%x, WscState=%d, bUPnPMsg=%d!\n", MsgType, pWscControl->WscState, bUPnPMsg)); if (bUPnPMsg) { #ifdef CONFIG_AP_SUPPORT if ((MsgType == WSC_MSG_EAP_RSP_ID) && (CurOpMode == AP_MODE)) { /* let it pass */ } else #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if ((MsgType ==WSC_MSG_EAP_REQ_START) && (CurOpMode == STA_MODE)) { /*let it pass */ } else #endif /* CONFIG_STA_SUPPORT */ if(MsgType ==WSC_MSG_M2 && pWscUPnPInfo->bUPnPInProgress == FALSE) { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { MAC_TABLE_ENTRY *tempEntry; tempEntry = MacTableLookup(pAdapter, &pWscControl->EntryAddr[0]); if (tempEntry) { if((tempEntry->Receive_EapolStart_EapRspId & WSC_ENTRY_GET_EAP_RSP_ID) == WSC_ENTRY_GET_EAP_RSP_ID) { goto Done; } } /* else cannot find the pEntry, so we need to handle this msg. */ } #endif /* CONFIG_AP_SUPPORT */ pWscUPnPInfo->bUPnPInProgress = TRUE; /* Set the WscState as "WSC_STATE_WAIT_RESP_ID" because UPnP start from this state. */ /* pWscControl->WscState = WSC_STATE_WAIT_RESP_ID; */ RTMPSetTimer(&pWscUPnPInfo->UPnPMsgTimer, WSC_UPNP_MSG_TIME_OUT); pWscUPnPInfo->bUPnPMsgTimerRunning = TRUE; } else { /* For other messages, we must make sure pWscUPnPInfo->bUPnPInProgress== TRUE */ if (pWscUPnPInfo->bUPnPInProgress == FALSE) { goto Done; } } } #ifdef WSC_V2_SUPPORT MaxWscDataLen = MaxWscDataLen + (UINT)pWscControl->WscV2Info.ExtraTlv.TlvLen; #endif /* WSC_V2_SUPPORT */ os_alloc_mem(NULL, (UCHAR **)&WscData, MaxWscDataLen); /* if( (WscData = kmalloc(WSC_MAX_DATA_LEN, GFP_ATOMIC)) == NULL) */ if (WscData == NULL) { DBGPRINT(RT_DEBUG_TRACE, ("WscData Allocate failed!\n")); goto Fail; } NdisZeroMemory(WscData, MaxWscDataLen); switch (MsgType) { case WSC_MSG_EAP_RSP_ID: DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx Identity\n")); case WSC_MSG_EAP_REQ_START: if (MsgType == WSC_MSG_EAP_REQ_START) DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx Wsc_Start\n")); if (pWscControl->RegData.ReComputePke == 1) { INT idx; DH_Len = sizeof(pWscControl->RegData.Pke); /* Enrollee 192 random bytes for DH key generation */ for (idx = 0; idx < 192; idx++) pWscControl->RegData.EnrolleeRandom[idx] = RandomByte(pAdapter); RT_DH_PublicKey_Generate ( WPS_DH_G_VALUE, sizeof(WPS_DH_G_VALUE), WPS_DH_P_VALUE, sizeof(WPS_DH_P_VALUE), pWscControl->RegData.EnrolleeRandom, sizeof(pWscControl->RegData.EnrolleeRandom), pWscControl->RegData.Pke, (UINT *) &DH_Len); pWscControl->RegData.ReComputePke = 0; } OpCode |= WSC_OPCODE_MSG; DataLen = BuildMessageM1(pAdapter, pWscControl, WscData); if(!bUPnPMsg) { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (pEntry && IS_ENTRY_CLIENT(pEntry)) WscDelWPARetryTimer(pAdapter); } #endif /* CONFIG_AP_SUPPORT */ pWscControl->EapMsgRunning = TRUE; pWscControl->WscStatus = STATUS_WSC_EAP_M1_SENT; } else /* Sometime out-of-band registrars (ex: Vista) get M1 for collecting information of device. */ pWscControl->WscStatus = STATUS_WSC_IDLE; /* Change the state to next one */ if (pWscControl->WscState < WSC_STATE_SENT_M1) pWscControl->WscState = WSC_STATE_SENT_M1; RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M1, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); break; case WSC_MSG_M2: DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx M2\n")); /* Receive M2, if we are at WSC_STATE_WAIT_M2 start, process it immediately */ if (pWscControl->WscState == WSC_STATE_SENT_M1 || pWscControl->WscState == WSC_STATE_RX_M2D) { /* Process M2 */ pWscControl->WscStatus = STATUS_WSC_EAP_M2_RECEIVED; NdisMoveMemory(pWscControl->RegData.PeerInfo.MacAddr, pWscControl->EntryAddr, 6); if ((rv = ProcessMessageM2(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, (pWscControl->EntryIfIdx & 0x0F), &pWscControl->RegData))) { goto Fail; } else { #ifdef CONFIG_AP_SUPPORT #ifdef WSC_V2_SUPPORT if ((CurOpMode == AP_MODE) && pWscControl->bSetupLock) { rv = WSC_ERROR_SETUP_LOCKED; goto Fail; } #endif /* WSC_V2_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ OpCode |= WSC_OPCODE_MSG; DataLen = BuildMessageM3(pAdapter, pWscControl, WscData); pWscControl->WscStatus = STATUS_WSC_EAP_M3_SENT; /* Change the state to next one */ pWscControl->WscState = WSC_STATE_WAIT_M4; RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M3, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } } break; case WSC_MSG_M2D: DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx M2D\n")); /* Receive M2D, if we are at WSC_STATE_WAIT_M2 start, process it immediately */ if (pWscControl->WscState == WSC_STATE_SENT_M1 || pWscControl->WscState == WSC_STATE_RX_M2D) { if ((rv = ProcessMessageM2D(pAdapter, Elem->Msg, Elem->MsgLen, &pWscControl->RegData))) goto Fail; pWscControl->WscStatus = STATUS_WSC_EAP_M2D_RECEIVED; if (CurOpMode == AP_MODE) { /* For VISTA SP1 internal registrar test */ OpCode |= WSC_OPCODE_NACK; pWscControl->RegData.SelfInfo.ConfigError = WSC_ERROR_NO_ERROR; DataLen = BuildMessageNACK(pAdapter, pWscControl, WscData); RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_NACK, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } else { /* When external registrar is Marvell station, */ /* wps station sends NACK may confuse or reset Marvell wps state machine. */ OpCode |= WSC_OPCODE_ACK; DataLen = BuildMessageACK(pAdapter, pWscControl, WscData); RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_ACK, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } /* Change the state to next one */ pWscControl->WscState = WSC_STATE_RX_M2D; } break; case WSC_MSG_M4: DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx M4\n")); /* Receive M4, if we are at WSC_STATE_WAIT_M4 start, process it immediately */ if (pWscControl->WscState == WSC_STATE_WAIT_M4) { /* Process M4 */ pWscControl->WscStatus = STATUS_WSC_EAP_M4_RECEIVED; if ((rv = ProcessMessageM4(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, &pWscControl->RegData))) { #ifdef CONFIG_AP_SUPPORT #ifdef WSC_V2_SUPPORT if (CurOpMode == AP_MODE) WscCheckPinAttackCount(pAdapter, pWscControl); #endif /* WSC_V2_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ goto Fail; } else { OpCode |= WSC_OPCODE_MSG; DataLen = BuildMessageM5(pAdapter, pWscControl, WscData); pWscControl->WscStatus = STATUS_WSC_EAP_M5_SENT; /* Change the state to next one */ pWscControl->WscState = WSC_STATE_WAIT_M6; RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M5, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } } break; case WSC_MSG_M6: DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx M6\n")); /* Receive M6, if we are at WSC_STATE_WAIT_M6 start, process it immediately */ if (pWscControl->WscState == WSC_STATE_WAIT_M6) { /* Process M6 */ pWscControl->WscStatus = STATUS_WSC_EAP_M6_RECEIVED; if ((rv=ProcessMessageM6(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, &pWscControl->RegData))) { #ifdef CONFIG_AP_SUPPORT #ifdef WSC_V2_SUPPORT if (CurOpMode == AP_MODE) WscCheckPinAttackCount(pAdapter, pWscControl); #endif /* WSC_V2_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ goto Fail; } else { OpCode |= WSC_OPCODE_MSG; DataLen = BuildMessageM7(pAdapter, pWscControl, WscData); pWscControl->WscStatus = STATUS_WSC_EAP_M7_SENT; /* Change the state to next one */ pWscControl->WscState = WSC_STATE_WAIT_M8; RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M7, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); /* Complete WPS with this STA. Delete it from WscPeerList for others STA to do WSC with AP */ if (pEntry) { RTMP_SEM_LOCK(&pWscControl->WscPeerListSemLock); WscDelListEntryByMAC(&pWscControl->WscPeerList, pEntry->Addr); RTMP_SEM_UNLOCK(&pWscControl->WscPeerListSemLock); } } } break; case WSC_MSG_M8: DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx M8\n")); /* Receive M8, if we are at WSC_STATE_WAIT_M6 start, process it immediately */ if (pWscControl->WscState == WSC_STATE_WAIT_M8) { /* Process M8 */ pWscControl->WscStatus = STATUS_WSC_EAP_M8_RECEIVED; if ((rv=ProcessMessageM8(pAdapter, Elem->Msg, Elem->MsgLen, pWscControl))) goto Fail; else { OpCode |= WSC_OPCODE_DONE; DataLen = BuildMessageDONE(pAdapter, pWscControl, WscData); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { /* Change the state to next one */ #ifdef APCLI_SUPPORT /* Ap Client only supports Inband(EAP)-Enrollee. */ if (!bUPnPMsg && pEntry && IS_ENTRY_APCLI(pEntry)) pWscControl->WscState = WSC_STATE_WAIT_EAPFAIL; else #endif /* APCLI_SUPPORT */ pWscControl->WscState = WSC_STATE_WAIT_ACK; pWscControl->RegData.ReComputePke = 0; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pWscControl->WscState = WSC_STATE_WAIT_EAPFAIL; pWscControl->WscStatus = STATUS_WSC_EAP_RSP_DONE_SENT; } #endif /* CONFIG_STA_SUPPORT */ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_DONE, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } } break; #ifdef CONFIG_AP_SUPPORT case WSC_MSG_WSC_ACK: DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Rx ACK\n")); /* Receive ACK */ if (pWscControl->WscState == WSC_STATE_WAIT_ACK) { /* Process ACK */ pWscControl->WscStatus = STATUS_WSC_EAP_RAP_RSP_ACK; /* Send out EAP-Fail */ WscSendEapFail(pAdapter, pWscControl, FALSE); pWscControl->WscState = WSC_STATE_CONFIGURED; pWscControl->WscStatus = STATUS_WSC_CONFIGURED; #ifdef P2P_SUPPORT pAdapter->P2pCfg.WscState = WSC_STATE_CONFIGURED; #ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT P2pSendWirelessEvent(pAdapter, RT_P2P_WPS_COMPLETED, NULL, NULL); #endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */ #endif /* P2P_SUPPORT */ } break; #endif /* CONFIG_AP_SUPPORT */ default: DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : Unsupported Msg Type\n")); break; } if (bUPnPMsg) { if ((MsgType == WSC_MSG_M8) && (pWscControl->WscState == WSC_STATE_WAIT_ACK)) { pWscControl->EapMsgRunning = FALSE; pWscControl->WscState = WSC_STATE_CONFIGURED; pWscControl->WscStatus = STATUS_WSC_CONFIGURED; #ifdef P2P_SUPPORT pAdapter->P2pCfg.WscState = WSC_STATE_CONFIGURED; #ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT P2pSendWirelessEvent(pAdapter, RT_P2P_WPS_COMPLETED, NULL, NULL); #endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */ #endif /* P2P_SUPPORT */ if(pWscUPnPInfo->bUPnPMsgTimerRunning == TRUE) { RTMPCancelTimer(&pWscUPnPInfo->UPnPMsgTimer, &Cancelled); pWscUPnPInfo->bUPnPMsgTimerRunning = FALSE; } pWscUPnPInfo->bUPnPInProgress = FALSE; pWscUPnPInfo->registrarID = 0; } } else { if (((MsgType == WSC_MSG_WSC_ACK) && (pWscControl->WscState == WSC_STATE_CONFIGURED)) || ((MsgType == WSC_MSG_M8) && (pWscControl->WscState == WSC_STATE_WAIT_ACK))) { RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); pWscControl->EapolTimerRunning = FALSE; pWscControl->EapMsgRunning = FALSE; /*NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); */ } } if(OpCode > WSC_OPCODE_UPNP_MASK) bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_NORMAL, WscData, DataLen, Elem->TimeStamp.u.LowPart, Elem->TimeStamp.u.HighPart, &pAdapter->CurrentAddress[0], CurOpMode); else if(OpCode > 0 && OpCode < WSC_OPCODE_UPNP_MASK) { if (pWscControl->WscState != WSC_STATE_CONFIGURED) { #ifdef WSC_V2_SUPPORT pWscControl->WscTxBufLen = 0; pWscControl->pWscCurBufIdx = NULL; pWscControl->bWscLastOne = TRUE; if (pWscControl->bWscFragment && (DataLen > pWscControl->WscFragSize)) { ASSERT(DataLen < MGMT_DMA_BUFFER_SIZE); NdisMoveMemory(pWscControl->pWscTxBuf, WscData, DataLen); pWscControl->WscTxBufLen = DataLen; NdisZeroMemory(WscData, DataLen); pWscControl->bWscLastOne = FALSE; pWscControl->bWscFirstOne = TRUE; NdisMoveMemory(WscData, pWscControl->pWscTxBuf, pWscControl->WscFragSize); DataLen = pWscControl->WscFragSize; pWscControl->WscTxBufLen -= pWscControl->WscFragSize; pWscControl->pWscCurBufIdx = (pWscControl->pWscTxBuf + pWscControl->WscFragSize); } #endif /* WSC_V2_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (pEntry && IS_ENTRY_APCLI(pEntry)) WscSendMessage(pAdapter, OpCode, WscData, DataLen, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP); else WscSendMessage(pAdapter, OpCode, WscData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) WscSendMessage(pAdapter, OpCode, WscData, DataLen, pWscControl, STA_MODE, EAP_CODE_RSP); #endif /* CONFIG_STA_SUPPORT */ } } else bUPnPStatus = TRUE; Fail: DBGPRINT(RT_DEBUG_TRACE, ("WscEapEnrolleeAction : rv = %d\n", rv)); if (rv) { #ifdef CONFIG_AP_SUPPORT #ifdef WSC_V2_SUPPORT if ((CurOpMode == AP_MODE) && pWscControl->bSetupLock) rv = WSC_ERROR_SETUP_LOCKED; #endif /* WSC_V2_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ if (rv <= WSC_ERROR_DEV_PWD_AUTH_FAIL) pWscControl->RegData.SelfInfo.ConfigError = rv; else if ((rv == WSC_ERROR_HASH_FAIL) || (rv == WSC_ERROR_HMAC_FAIL)) pWscControl->RegData.SelfInfo.ConfigError = WSC_ERROR_DECRYPT_CRC_FAIL; switch(rv) { case WSC_ERROR_DEV_PWD_AUTH_FAIL: pWscControl->WscStatus = STATUS_WSC_ERROR_DEV_PWD_AUTH_FAIL; break; default: pWscControl->WscStatus = STATUS_WSC_FAIL; break; } RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_FAIL, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); if (bUPnPMsg) { if (pWscUPnPInfo->bUPnPMsgTimerRunning == TRUE) { RTMPCancelTimer(&pWscUPnPInfo->UPnPMsgTimer, &Cancelled); pWscUPnPInfo->bUPnPMsgTimerRunning = FALSE; } pWscUPnPInfo->bUPnPInProgress = FALSE; } else WscSendNACK(pAdapter, pEntry, pWscControl); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { #ifdef P2P_SUPPORT if (P2P_CLI_ON(pAdapter)) pWscControl->WscState = WSC_STATE_WAIT_DISCONN; else #endif /* P2P_SUPPORT */ pWscControl->WscState = WSC_STATE_OFF; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pWscControl->WscState = WSC_STATE_WAIT_DISCONN; if (pWscControl->WscSsid.SsidLength) { pAdapter->MlmeAux.AutoReconnectSsidLen = pWscControl->WscSsid.SsidLength; NdisZeroMemory(&pAdapter->MlmeAux.AutoReconnectSsid[0], MAX_LEN_OF_SSID); NdisMoveMemory(&pAdapter->MlmeAux.AutoReconnectSsid[0], &pWscControl->WscSsid.Ssid[0], pWscControl->WscSsid.SsidLength); } else pAdapter->MlmeAux.AutoReconnectSsidLen = 0; } #endif /* CONFIG_STA_SUPPORT */ /*NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); */ /*pWscControl->WscMode = 1; */ bUPnPStatus = FALSE; } Done: if(WscData) os_free_mem(NULL, WscData); if(bUPnPMsg && (bUPnPStatus == FALSE)) WscUPnPErrHandle(pAdapter, pWscControl, Elem->TimeStamp.u.LowPart); rv = 0; #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (((bUPnPMsg || (pEntry && IS_ENTRY_CLIENT(pEntry))) && (pWscControl->WscState == WSC_STATE_CONFIGURED || pWscControl->WscState == WSC_STATE_WAIT_ACK)) #ifdef APCLI_SUPPORT ||((!bUPnPMsg && pEntry && IS_ENTRY_APCLI(pEntry)) && (pWscControl->WscState == WSC_STATE_WAIT_EAPFAIL || pWscControl->WscState == WSC_STATE_CONFIGURED)) #endif /* APCLI_SUPPORT */ ) { rv = 1; } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if ((pWscControl->WscState == WSC_STATE_WAIT_EAPFAIL) || (pWscControl->WscState == WSC_STATE_CONFIGURED)) { rv = 1; } } #endif /* CONFIG_STA_SUPPORT */ if (rv == 1) { #ifdef WSC_LED_SUPPORT UCHAR WPSLEDStatus; #endif /* WSC_LED_SUPPORT */ pWscControl->bWscTrigger = FALSE; pWscControl->RegData.ReComputePke = 1; RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); if (pWscControl->Wsc2MinsTimerRunning) { pWscControl->Wsc2MinsTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled); } #ifdef IWSC_SUPPORT if ((pAdapter->OpMode == OPMODE_STA) && (pAdapter->StaCfg.BssType == BSS_ADHOC)) { pAdapter->StaCfg.IWscInfo.bReStart = TRUE; if (pAdapter->StaCfg.IWscInfo.bIWscT1TimerRunning) { pAdapter->StaCfg.IWscInfo.bIWscT1TimerRunning = FALSE; RTMPCancelTimer(&pAdapter->StaCfg.IWscInfo.IWscT1Timer, &Cancelled); } pAdapter->StaCfg.IWscInfo.bIWscDevQueryReqTimerRunning = TRUE; } #endif /* IWSC_SUPPORT */ if ((pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED) #ifdef CONFIG_AP_SUPPORT || (pWscControl->bWCNTest == TRUE) #ifdef WSC_V2_SUPPORT || (pWscControl->WscV2Info.bEnableWpsV2 && ((CurOpMode == AP_MODE) && !pWscControl->bSetupLock)) #endif /* WSC_V2_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ ) { pWscControl->WscStatus = STATUS_WSC_CONFIGURED; pWscControl->WscConfStatus = WSC_SCSTATE_CONFIGURED; pWscControl->WscMode = 1; RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_SUCCESS, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); #ifdef P2P_SUPPORT /*RTMPCancelTimer(&pAdapter->P2pCfg.P2pWscTimer, &Cancelled);*/ if (P2P_GO_ON(pAdapter) && (pWscControl->EntryIfIdx != BSS0) && pEntry) { UCHAR P2pIdx = P2P_NOT_FOUND; P2pIdx = P2pGroupTabSearch(pAdapter, pEntry->Addr); if (P2pIdx != P2P_NOT_FOUND) { PRT_P2P_CLIENT_ENTRY pP2pEntry = &pAdapter->P2pTable.Client[P2pIdx]; // Update p2p Entry's state. pP2pEntry->P2pClientState = P2PSTATE_CLIENT_WPS_DONE; } } // default set extended listening to zero for each connection. If this is persistent, will set it. pAdapter->P2pCfg.ExtListenInterval = 0; pAdapter->P2pCfg.ExtListenPeriod = 0; if (IS_PERSISTENT_ON(pAdapter) && pEntry && (pEntry->bP2pClient == TRUE)) { UCHAR P2pIdx = P2P_NOT_FOUND; P2pIdx = P2pGroupTabSearch(pAdapter, pEntry->Addr); if (IS_P2P_GO_ENTRY(pEntry)) DBGPRINT(RT_DEBUG_ERROR, ("pEntry is P2P GO.\n")); else if (IS_P2P_CLI_ENTRY(pEntry)) DBGPRINT(RT_DEBUG_ERROR, ("pEntry is P2P CLIENT.\n")); else DBGPRINT(RT_DEBUG_ERROR, ("pEntry is P2P NONE.\n")); if ((P2pIdx != P2P_NOT_FOUND) && (IS_P2P_GO_ENTRY(pEntry) || IS_P2P_CLI_ENTRY(pEntry))) { DBGPRINT(RT_DEBUG_ERROR, ("P2pWPSDone- Save to persistent entry. GrpCap= %x \n", pAdapter->P2pTable.Client[P2pIdx].GroupCapability)); DBGPRINT(RT_DEBUG_ERROR, ("2. P2pWPSDone- Set Extended timing !!!!!!!\n")); DBGPRINT(RT_DEBUG_ERROR, (" ======== Profile :: Cnt = %d ========\n", pWscControl->WscProfile.ProfileCnt)); DBGPRINT(RT_DEBUG_ERROR, (" SSID[%d] = %s.\n", pWscControl->WscProfile.Profile[0].SSID.SsidLength, pWscControl->WscProfile.Profile[0].SSID.Ssid)); DBGPRINT(RT_DEBUG_ERROR, (" AuthType = %d. EncrType = %d.\n", pWscControl->WscProfile.Profile[0].AuthType, pWscControl->WscProfile.Profile[0].EncrType)); DBGPRINT(RT_DEBUG_ERROR, (" MAC = %02x:%02x:%02x:%02x:%02x:%02x.\n", PRINT_MAC(pWscControl->WscProfile.Profile[0].MacAddr))); DBGPRINT(RT_DEBUG_ERROR, (" KeyLen = %d. KeyIdx = %d.\n", pWscControl->WscProfile.Profile[0].KeyLength, pWscControl->WscProfile.Profile[0].KeyIndex)); DBGPRINT(RT_DEBUG_ERROR, (" Key :: %02x %02x %02x %02x %02x %02x %02x %02x\n", pWscControl->WscProfile.Profile[0].Key[0], pWscControl->WscProfile.Profile[0].Key[1], pWscControl->WscProfile.Profile[0].Key[2], pWscControl->WscProfile.Profile[0].Key[3], pWscControl->WscProfile.Profile[0].Key[4], pWscControl->WscProfile.Profile[0].Key[5], pWscControl->WscProfile.Profile[0].Key[6], pWscControl->WscProfile.Profile[0].Key[7])); DBGPRINT(RT_DEBUG_ERROR, (" %02x %02x %02x %02x %02x %02x %02x %02x\n", pWscControl->WscProfile.Profile[0].Key[8], pWscControl->WscProfile.Profile[0].Key[9], pWscControl->WscProfile.Profile[0].Key[10], pWscControl->WscProfile.Profile[0].Key[11], pWscControl->WscProfile.Profile[0].Key[12], pWscControl->WscProfile.Profile[0].Key[13], pWscControl->WscProfile.Profile[0].Key[14], pWscControl->WscProfile.Profile[0].Key[15])); P2pPerstTabInsert(pAdapter, pEntry->Addr, &pWscControl->WscProfile.Profile[0]); // this is a persistent connection. pAdapter->P2pCfg.ExtListenInterval = P2P_EXT_LISTEN_INTERVAL; pAdapter->P2pCfg.ExtListenPeriod = P2P_EXT_LISTEN_PERIOD; } } #endif //P2P_SUPPORT // #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { pWscControl->RegData.SelfInfo.ScState = pWscControl->WscConfStatus; #ifdef APCLI_SUPPORT if (!bUPnPMsg && pEntry && IS_ENTRY_APCLI(pEntry)) { POS_COOKIE pObj = (POS_COOKIE) pAdapter->OS_Cookie; INT old_if_type = pObj->ioctl_if_type; pObj->ioctl_if_type = INT_APCLI; WscWriteConfToApCliCfg(pAdapter, pWscControl, &pWscControl->WscProfile.Profile[0], TRUE); pObj->ioctl_if_type = old_if_type; /*#ifdef KTHREAD_SUPPORT */ /* WAKE_UP(&(pAdapter->wscTask)); */ /*#else */ /* RTMP_SEM_EVENT_UP(&(pAdapter->wscTask.taskSema)); */ /*#endif */ RtmpOsTaskWakeUp(&(pAdapter->wscTask)); } else #endif /* APCLI_SUPPORT */ { RTMPSetTimer(&pWscControl->WscUpdatePortCfgTimer, 1000); pWscControl->WscUpdatePortCfgTimerRunning = TRUE; } if (bUPnPMsg || (pEntry && IS_ENTRY_CLIENT(pEntry))) { WscBuildBeaconIE(pAdapter, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode); WscBuildProbeRespIE(pAdapter, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode); APUpdateBeaconFrame(pAdapter, pWscControl->EntryIfIdx & 0x0F); } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pWscControl->WscConfMode = WSC_DISABLE; if (bUPnPMsg) { pWscControl->WscState = WSC_STATE_OFF; WscLinkDown(pAdapter); } if (pWscControl->WscDriverAutoConnect != 0) { pAdapter->StaCfg.bAutoConnectByBssid = TRUE; pWscControl->WscProfile.ApplyProfileIdx = 0; /* add by johnli, fix WPS test plan 5.1.1 */ { WscWriteConfToPortCfg(pAdapter, pWscControl, &pWscControl->WscProfile.Profile[0], TRUE); pAdapter->WriteWscCfgToDatFile = (pWscControl->EntryIfIdx & 0x0F); /*#ifdef KTHREAD_SUPPORT */ /* WAKE_UP(&(pAdapter->wscTask)); */ /*#else */ /* RTMP_SEM_EVENT_UP(&(pAdapter->wscTask.taskSema)); */ /*#endif */ RtmpOsTaskWakeUp(&(pAdapter->wscTask)); } #ifdef IWSC_SUPPORT if ((pAdapter->StaCfg.BssType == BSS_ADHOC)&& (pAdapter->StaCfg.IWscInfo.bIWscDevQueryReqTimerRunning == FALSE)) { pAdapter->StaCfg.IWscInfo.bIWscDevQueryReqTimerRunning = TRUE; RTMPSetTimer(&pAdapter->StaCfg.IWscInfo.IWscDevQueryTimer, 200); } #endif /* IWSC_SUPPORT */ } } #endif /* CONFIG_STA_SUPPORT */ } #ifdef WSC_LED_SUPPORT /* The protocol is finished. */ WPSLEDStatus = LED_WPS_SUCCESS; RTMPSetLED(pAdapter, WPSLEDStatus); #endif /* WSC_LED_SUPPORT */ } } #ifdef CONFIG_AP_SUPPORT /* ============================================================================ Proxy Proxy Proxy ============================================================================ */ VOID WscEapApProxyAction( IN PRTMP_ADAPTER pAdapter, IN MLME_QUEUE_ELEM *Elem, IN UCHAR MsgType, IN MAC_TABLE_ENTRY *pEntry, IN PWSC_CTRL pWscControl) { PUCHAR WscData = NULL; BOOLEAN sendToUPnP = FALSE, bUPnPStatus = FALSE, Cancelled; int reqID = 0; WSC_UPNP_NODE_INFO *pWscUPnPInfo = &pWscControl->WscUPnPNodeInfo; UINT MaxWscDataLen = WSC_MAX_DATA_LEN; DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction Enter!\n")); if (Elem->MsgType == WSC_EAPOL_UPNP_MSG) { reqID = Elem->TimeStamp.u.LowPart; if(reqID > 0) sendToUPnP = TRUE; } DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction():pEntry=%p, ElemMsgType=%ld, MsgType=%d!\n", pEntry, Elem->MsgType, MsgType)); if ((pWscControl->WscActionMode != WSC_PROXY) || ((Elem->MsgType == WSC_EAPOL_PACKET_MSG) && (pEntry == NULL))) { DBGPRINT(RT_DEBUG_TRACE, ("EarlyCheckFailed: gWscActionMode=%d, pEntry=%p!\n", pWscControl->WscActionMode, pEntry)); goto Fail; } #ifdef WSC_V2_SUPPORT MaxWscDataLen = MaxWscDataLen + (UINT)pWscControl->WscV2Info.ExtraTlv.TlvLen; #endif /* WSC_V2_SUPPORT */ os_alloc_mem(NULL, (UCHAR **)&WscData, MaxWscDataLen); /* if ((WscData = kmalloc(WSC_MAX_DATA_LEN, GFP_ATOMIC)) == NULL) */ if (WscData == NULL) { DBGPRINT(RT_DEBUG_TRACE, ("WscData Allocate failed!\n")); goto Fail; } NdisZeroMemory(WscData, MaxWscDataLen); /* Base on state doing the Msg, State change diagram */ if (Elem->MsgType == WSC_EAPOL_UPNP_MSG) { /* WSC message send from UPnP. */ switch (MsgType) { case WSC_MSG_M2: case WSC_MSG_M4: case WSC_MSG_M6: case WSC_MSG_M8: DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: Rx WscMsg(%d) from UPnP, eventID=0x%x!\n", MsgType, reqID)); WscSendMessage(pAdapter, WSC_OPCODE_MSG, Elem->Msg, Elem->MsgLen, pWscControl, AP_MODE, EAP_CODE_REQ); /*Notify the UPnP daemon which remote registar is negotiating with enrollee. */ if (MsgType == WSC_MSG_M2) { pWscUPnPInfo->registrarID = Elem->TimeStamp.u.HighPart; DBGPRINT(RT_DEBUG_TRACE, ("%s():registrarID=0x%x!\n", __FUNCTION__, pWscUPnPInfo->registrarID)); bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_MGMT, WSC_UPNP_MGMT_SUB_REG_SELECT, (PUCHAR)(&pWscUPnPInfo->registrarID), sizeof(UINT), 0, 0, NULL, AP_MODE); /*Reset the UPnP timer and status. */ if (pWscControl->bM2DTimerRunning == TRUE) { RTMPCancelTimer(&pWscControl->M2DTimer, &Cancelled); pWscControl->bM2DTimerRunning = FALSE; } pWscControl->M2DACKBalance = 0; pWscUPnPInfo->registrarID = 0; } if (MsgType == WSC_MSG_M8) { WscBuildBeaconIE(pAdapter, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, AP_MODE); WscBuildProbeRespIE(pAdapter, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, pWscControl->EntryIfIdx, NULL, 0, AP_MODE); APUpdateBeaconFrame(pAdapter, pWscControl->EntryIfIdx & 0x0F); } break; case WSC_MSG_M2D: DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: Rx WscMsg M2D(%d) from UPnP, eventID=0x%x!\n", MsgType, reqID)); /*If it's send by UPnP Action, response ok directly to remote UPnP Control Point! */ if (reqID > 0) bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_ACK, 0, 0, reqID, 0, NULL, AP_MODE); /*Send M2D to wireless station. */ WscSendMessage(pAdapter, WSC_OPCODE_MSG, Elem->Msg, Elem->MsgLen, pWscControl, AP_MODE, EAP_CODE_REQ); pWscControl->M2DACKBalance++; if ((pWscUPnPInfo->registrarID == 0) && (pWscControl->bM2DTimerRunning == FALSE)) { /* Add M2D timer used to trigger the EAPFail Packet! */ RTMPSetTimer(&pWscControl->M2DTimer, WSC_UPNP_M2D_TIME_OUT); pWscControl->bM2DTimerRunning = TRUE; } break; case WSC_MSG_WSC_NACK: default: DBGPRINT(RT_DEBUG_TRACE, ("Recv WscMsg(%d) from UPnP, request EventID=%d! drop it!\n", MsgType, reqID)); break; } } else { /*WSC msg send from EAP. */ switch (MsgType) { case WSC_MSG_M1: case WSC_MSG_M3: case WSC_MSG_M5: case WSC_MSG_M7: DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: Rx WscMsg(%d) from EAP\n", MsgType)); /*This msg send to event-based external registrar */ if (MsgType == WSC_MSG_M1) { bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_TO_ALL, Elem->Msg, Elem->MsgLen, 0, 0, &pWscControl->EntryAddr[0], AP_MODE); pWscControl->WscState = WSC_STATE_SENT_M1; } else bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_TO_ALL, Elem->Msg, Elem->MsgLen, 0, pWscUPnPInfo->registrarID, &pWscControl->EntryAddr[0], AP_MODE); break; case WSC_MSG_WSC_ACK: DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: Rx WSC_ACK from EAP\n")); /* The M2D must appeared before the ACK, so we just need sub it when (pWscUPnPInfo->M2DACKBalance > 0) */ if (pWscControl->M2DACKBalance > 0) pWscControl->M2DACKBalance--; break; case WSC_MSG_WSC_DONE: DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: Rx WSC_DONE from EAP\n")); DBGPRINT(RT_DEBUG_TRACE, ("WscEapApProxyAction: send WSC_DONE to UPnP Registrar!\n")); /*Send msg to event-based external registrar */ bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_TO_ONE, Elem->Msg, Elem->MsgLen, 0, pWscUPnPInfo->registrarID, &pWscControl->EntryAddr[0], AP_MODE); /*Send EAPFail to wireless station to finish the whole process. */ WscSendEapFail(pAdapter, pWscControl, FALSE); RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); pWscControl->EapolTimerRunning = FALSE; pEntry->bWscCapable = FALSE; pWscControl->EapMsgRunning = FALSE; NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); if (pWscControl->Wsc2MinsTimerRunning) { pWscControl->Wsc2MinsTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled); } break; default: DBGPRINT(RT_DEBUG_TRACE, ("Recv WSC Msg(%d) from EAP , it's impossible, drop it!\n", MsgType)); break; } } Fail: if (WscData) os_free_mem(NULL, WscData); if (sendToUPnP && (bUPnPStatus == FALSE)) { DBGPRINT(RT_DEBUG_TRACE, ("Need to send UPnP but bUPnPStatus is false!MsgType=%d, regID=0x%x!\n", MsgType, reqID)); WscUPnPErrHandle(pAdapter, pWscControl, reqID); } } #endif /* CONFIG_AP_SUPPORT */ /* ============================================================================ Registrar Registrar Registrar ============================================================================ */ VOID WscEapRegistrarAction( IN PRTMP_ADAPTER pAdapter, IN MLME_QUEUE_ELEM *Elem, IN UCHAR MsgType, IN MAC_TABLE_ENTRY *pEntry, IN PWSC_CTRL pWscControl) { INT DataLen = 0, rv = 0; UCHAR OpCode = 0; UCHAR *WscData = NULL; BOOLEAN bUPnPMsg, bUPnPStatus = FALSE, Cancelled; WSC_UPNP_NODE_INFO *pWscUPnPInfo = &pWscControl->WscUPnPNodeInfo; UINT MaxWscDataLen = WSC_MAX_DATA_LEN; UCHAR CurOpMode = 0xFF; #ifdef P2P_SUPPORT BOOLEAN bReadOwnPIN = FALSE; #endif /* P2P_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction Enter!\n")); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter) CurOpMode = AP_MODE; #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAdapter) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (Elem->OpMode != OPMODE_STA) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif // CONFIG_STA_SUPPORT // bUPnPMsg = Elem->MsgType == WSC_EAPOL_UPNP_MSG ? TRUE : FALSE; if(bUPnPMsg) { if(MsgType == WSC_MSG_M1) { /* It's a M1 message, we may need to initialize our state machine. */ if ((pWscControl->WscActionMode == WSC_REGISTRAR) && (pWscControl->EntryIfIdx == WSC_INIT_ENTRY_APIDX) && (pWscControl->WscState < WSC_STATE_WAIT_M1) && (pWscUPnPInfo->bUPnPInProgress == FALSE)) { pWscUPnPInfo->bUPnPInProgress = TRUE; /*Set the WscState as "WSC_STATE_WAIT_RESP_ID" because UPnP start from this state. */ pWscControl->WscState = WSC_STATE_WAIT_M1; RTMPSetTimer(&pWscUPnPInfo->UPnPMsgTimer, WSC_UPNP_MSG_TIME_OUT); pWscUPnPInfo->bUPnPMsgTimerRunning = TRUE; } } OpCode = WSC_OPCODE_UPNP_MASK; } else { if (pWscControl->EapolTimerRunning) pWscControl->EapolTimerRunning = FALSE; } #ifdef WSC_V2_SUPPORT MaxWscDataLen = MaxWscDataLen + (UINT)pWscControl->WscV2Info.ExtraTlv.TlvLen; #endif /* WSC_V2_SUPPORT */ os_alloc_mem(NULL, (UCHAR **)&WscData, MaxWscDataLen); /* if( (WscData = kmalloc(WSC_MAX_DATA_LEN, GFP_ATOMIC)) == NULL) */ if (WscData == NULL) { DBGPRINT(RT_DEBUG_TRACE, ("WscData Allocate failed!\n")); goto Fail; } NdisZeroMemory(WscData, MaxWscDataLen); /* Base on state doing the Msg, State change diagram */ switch (MsgType) { case WSC_MSG_M1: DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Rx M1\n")); /* Receive M1, if we are at WSC_STATE_WAIT_M1 start, process it immediately */ pWscControl->WscStatus = STATUS_WSC_EAP_M1_RECEIVED; if (pWscControl->WscState == WSC_STATE_WAIT_M1) { OpCode |= WSC_OPCODE_MSG; /* Process M1 */ if ((rv=ProcessMessageM1(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, &pWscControl->RegData))) goto Fail; else { BOOLEAN bSendM2D = TRUE; #ifdef P2P_SUPPORT /* If own UI is limited UI, we need to use own PIN not PIN of Enrollee. */ if (P2P_GO_ON(pAdapter) && (pWscControl->EntryIfIdx != BSS0)) { if ((pAdapter->P2pCfg.ConfigMethod & WSC_CONFMET_KEYPAD) == 0) bReadOwnPIN = TRUE; } if (bReadOwnPIN) { pWscControl->WscPinCodeLen = pWscControl->WscEnrolleePinCodeLen; WscGetRegDataPIN(pAdapter, pWscControl->WscEnrolleePinCode, pWscControl); } #endif /* P2P_SUPPORT */ if (pWscControl->bWscTrigger && (!pWscControl->bWscAutoTigeer)) { if (((pWscControl->WscMode == WSC_PBC_MODE) || (pWscControl->WscMode == WSC_SMPBC_MODE)) || (pWscControl->WscMode == WSC_PIN_MODE && pWscControl->WscPinCode != 0)) bSendM2D = FALSE; } if (bSendM2D) { DataLen = BuildMessageM2D(pAdapter, pWscControl, WscData); pWscControl->WscState = WSC_STATE_SENT_M2D; pWscControl->M2DACKBalance++; if (pWscControl->bM2DTimerRunning == FALSE) { // Add M2D timer used to trigger the EAPFail Packet! RTMPSetTimer(&pWscControl->M2DTimer, WSC_UPNP_M2D_TIME_OUT); pWscControl->bM2DTimerRunning = TRUE; } } else { pWscControl->WscStatus = STATUS_WSC_EAP_M2_SENT; DataLen = BuildMessageM2(pAdapter, pWscControl, WscData); /* Change the state to next one */ pWscControl->WscState = WSC_STATE_WAIT_M3; #ifdef CONFIG_STA_SUPPORT if ((CurOpMode == STA_MODE) && INFRA_ON(pAdapter)) { if (!bUPnPMsg) pWscControl->WscConfStatus = pWscControl->bConfiguredAP ? WSC_SCSTATE_UNCONFIGURED : WSC_SCSTATE_CONFIGURED; } #endif /* CONFIG_STA_SUPPORT */ RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M2, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } } } break; case WSC_MSG_M3: /* Receive M3 */ DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Rx M3\n")); if (pWscControl->WscState == WSC_STATE_WAIT_M3) { pWscControl->WscStatus = STATUS_WSC_EAP_M3_RECEIVED; if((rv = ProcessMessageM3(pAdapter, Elem->Msg, Elem->MsgLen, &pWscControl->RegData))) goto Fail; else { OpCode |= WSC_OPCODE_MSG; DataLen = BuildMessageM4(pAdapter, pWscControl, WscData); pWscControl->WscStatus = STATUS_WSC_EAP_M4_SENT; /* Change the state to next one */ pWscControl->WscState = WSC_STATE_WAIT_M5; RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M4, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } } break; case WSC_MSG_M5: DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Rx M5\n")); if (pWscControl->WscState == WSC_STATE_WAIT_M5) { pWscControl->WscStatus = STATUS_WSC_EAP_M5_RECEIVED; if ((rv=ProcessMessageM5(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, &pWscControl->RegData))) goto Fail; else { OpCode |= WSC_OPCODE_MSG; DataLen = BuildMessageM6(pAdapter, pWscControl, WscData); pWscControl->WscStatus = STATUS_WSC_EAP_M6_SENT; /* Change the state to next one */ pWscControl->WscState = WSC_STATE_WAIT_M7; RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M6, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } } break; case WSC_MSG_M7: DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Rx M7\n")); if (pWscControl->WscState == WSC_STATE_WAIT_M7) { pWscControl->WscStatus = STATUS_WSC_EAP_M7_RECEIVED; if ((rv=ProcessMessageM7(pAdapter, pWscControl, Elem->Msg, Elem->MsgLen, &pWscControl->RegData))) goto Fail; else { if ( #ifdef CONFIG_AP_SUPPORT (CurOpMode == AP_MODE) || #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT ((CurOpMode == STA_MODE) && ((pWscControl->bConfiguredAP == FALSE) #ifdef WSC_V2_SUPPORT /* Check AP is v2 or v1, Check WscV2 Enabled or not */ || (pWscControl->WscV2Info.bForceSetAP && pWscControl->WscV2Info.bEnableWpsV2 && (pWscControl->RegData.PeerInfo.Version2!= 0)) #endif /* WSC_V2_SUPPORT */ )) || #endif /* CONFIG_STA_SUPPORT */ (0)) { OpCode |= WSC_OPCODE_MSG; #ifdef IWSC_SUPPORT if ((pAdapter->OpMode == OPMODE_STA) && (pAdapter->StaCfg.BssType == BSS_ADHOC)) pWscControl->WscConfStatus = WSC_SCSTATE_CONFIGURED; #endif /* IWSC_SUPPORT */ DataLen = BuildMessageM8(pAdapter, pWscControl, WscData); pWscControl->WscStatus = STATUS_WSC_EAP_M8_SENT; /* Change the state to next one */ pWscControl->WscState = WSC_STATE_WAIT_DONE; RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_M8, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); #ifdef CONFIG_AP_SUPPORT #ifdef WSC_V2_SUPPORT if (pWscControl->WscV2Info.bEnableWpsV2 && (CurOpMode == AP_MODE)) WscAddEntryToAclList(pAdapter, pEntry->apidx, pEntry->Addr); #endif /* WSC_V2_SUPPORT */ /* 1. Complete WPS with this STA. Delete it from WscPeerList for others STA to do WSC with AP 2. Some WPS STA will send dis-assoc close to WSC_DONE then AP will miss WSC_DONE from STA; hence we need to call WscDelListEntryByMAC here. */ if (pEntry && (CurOpMode == AP_MODE)) { RTMP_SEM_LOCK(&pWscControl->WscPeerListSemLock); WscDelListEntryByMAC(&pWscControl->WscPeerList, pEntry->Addr); RTMP_SEM_UNLOCK(&pWscControl->WscPeerListSemLock); } #endif /* CONFIG_AP_SUPPORT */ } #ifdef CONFIG_STA_SUPPORT else if ((CurOpMode == STA_MODE) && (pWscControl->bConfiguredAP == TRUE)) { /* Some WPS AP expects to receive WSC_NACK when AP is configured */ OpCode |= WSC_OPCODE_NACK; DataLen = BuildMessageNACK(pAdapter, pWscControl, WscData); pWscControl->WscStatus = STATUS_WSC_CONFIGURED; pWscControl->WscState = WSC_STATE_CONFIGURED; pWscControl->EapMsgRunning = FALSE; RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_NACK, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } #endif /* CONFIG_STA_SUPPORT */ } } break; case WSC_MSG_WSC_DONE: DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Rx DONE\n")); if (pWscControl->WscState == WSC_STATE_WAIT_DONE) { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { pWscControl->WscStatus = STATUS_WSC_EAP_RAP_RSP_DONE_SENT; /* Send EAP-Fail */ WscSendEapFail(pAdapter, pWscControl, FALSE); pWscControl->WscStatus = STATUS_WSC_CONFIGURED; #ifdef P2P_SUPPORT if (P2P_GO_ON(pAdapter) && (pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED) && (pWscControl == &pAdapter->ApCfg.MBSSID[MAIN_MBSSID].WscControl)) pAdapter->P2pCfg.bStopAuthRsp = TRUE; #endif /* P2P_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if ((CurOpMode == STA_MODE) && ADHOC_ON(pAdapter)) { WscSendEapFail(pAdapter, pWscControl, FALSE); } else { OpCode |= WSC_OPCODE_ACK; DataLen = BuildMessageACK(pAdapter, pWscControl, WscData); RTMPSendWirelessEvent(pAdapter, IW_WSC_SEND_ACK, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); } #ifdef IWSC_SUPPORT if ((pAdapter->StaCfg.BssType == BSS_ADHOC) && (pWscControl->WscMode == WSC_SMPBC_MODE)) { pAdapter->StaCfg.IWscInfo.IWscSmpbcAcceptCount--; pWscControl->WscStatus = STATUS_WSC_CONFIGURED; if (pEntry && pEntry->bIWscSmpbcAccept) { pEntry->bIWscSmpbcAccept = FALSE; WscDelListEntryByMAC(&pWscControl->WscPeerList, pEntry->Addr); } pAdapter->StaCfg.IWscInfo.SmpbcEnrolleeCount++; } else #endif /* IWSC_SUPPORT */ pWscControl->WscStatus = STATUS_WSC_CONFIGURED; } #endif /* CONFIG_STA_SUPPORT */ pWscControl->WscState = WSC_STATE_CONFIGURED; RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_SUCCESS, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); #ifdef P2P_SUPPORT /*RTMPCancelTimer(&pAdapter->P2pCfg.P2pWscTimer, &Cancelled);*/ if (P2P_GO_ON(pAdapter) && pEntry && pWscControl->EntryIfIdx != BSS0) { UCHAR P2pIdx = P2P_NOT_FOUND; P2pIdx = P2pGroupTabSearch(pAdapter, pEntry->Addr); if (P2pIdx != P2P_NOT_FOUND) { PRT_P2P_CLIENT_ENTRY pP2pEntry = &pAdapter->P2pTable.Client[P2pIdx]; // Update p2p Entry's state. pP2pEntry->P2pClientState = P2PSTATE_CLIENT_WPS_DONE; } } // default set extended listening to zero for each connection. If this is persistent, will set it. pAdapter->P2pCfg.ExtListenInterval = 0; pAdapter->P2pCfg.ExtListenPeriod = 0; pAdapter->P2pCfg.WscState = WSC_STATE_CONFIGURED; #ifdef RT_P2P_SPECIFIC_WIRELESS_EVENT P2pSendWirelessEvent(pAdapter, RT_P2P_WPS_COMPLETED, NULL, NULL); #endif /* RT_P2P_SPECIFIC_WIRELESS_EVENT */ if (IS_PERSISTENT_ON(pAdapter) && pEntry && (pEntry->bP2pClient == TRUE)) { UCHAR P2pIdx = P2P_NOT_FOUND; P2pIdx = P2pGroupTabSearch(pAdapter, pEntry->Addr); if (IS_P2P_GO_ENTRY(pEntry)) DBGPRINT(RT_DEBUG_ERROR, ("pEntry is P2P GO.\n")); else if (IS_P2P_CLI_ENTRY(pEntry)) DBGPRINT(RT_DEBUG_ERROR, ("pEntry is P2P CLIENT.\n")); else DBGPRINT(RT_DEBUG_ERROR, ("pEntry is P2P NONE[%d].\n", pEntry->EntryType)); if ((P2pIdx != P2P_NOT_FOUND) && (IS_P2P_GO_ENTRY(pEntry) || IS_P2P_CLI_ENTRY(pEntry))) { DBGPRINT(RT_DEBUG_ERROR, ("P2pWPSDone- Save to persistent entry. GrpCap= %x \n", pAdapter->P2pTable.Client[P2pIdx].GroupCapability)); DBGPRINT(RT_DEBUG_ERROR, ("1. P2pWPSDone- Set Extended timing !!!!!!!\n")); DBGPRINT(RT_DEBUG_ERROR, (" ======== Profile :: Cnt = %d ========\n", pWscControl->WscProfile.ProfileCnt)); DBGPRINT(RT_DEBUG_ERROR, (" SSID[%d] = %s.\n", pWscControl->WscProfile.Profile[0].SSID.SsidLength, pWscControl->WscProfile.Profile[0].SSID.Ssid)); DBGPRINT(RT_DEBUG_ERROR, (" AuthType = %x. EncrType = %x.\n", pWscControl->WscProfile.Profile[0].AuthType, pWscControl->WscProfile.Profile[0].EncrType)); DBGPRINT(RT_DEBUG_ERROR, (" MAC = %02x:%02x:%02x:%02x:%02x:%02x.\n", PRINT_MAC(pWscControl->WscProfile.Profile[0].MacAddr))); DBGPRINT(RT_DEBUG_ERROR, (" KeyLen = %d. KeyIdx = %d.\n", pWscControl->WscProfile.Profile[0].KeyLength, pWscControl->WscProfile.Profile[0].KeyIndex)); DBGPRINT(RT_DEBUG_ERROR, (" Key :: %02x %02x %02x %02x %02x %02x %02x %02x\n", pWscControl->WscProfile.Profile[0].Key[0], pWscControl->WscProfile.Profile[0].Key[1], pWscControl->WscProfile.Profile[0].Key[2], pWscControl->WscProfile.Profile[0].Key[3], pWscControl->WscProfile.Profile[0].Key[4], pWscControl->WscProfile.Profile[0].Key[5], pWscControl->WscProfile.Profile[0].Key[6], pWscControl->WscProfile.Profile[0].Key[7])); DBGPRINT(RT_DEBUG_ERROR, (" %02x %02x %02x %02x %02x %02x %02x %02x\n", pWscControl->WscProfile.Profile[0].Key[8], pWscControl->WscProfile.Profile[0].Key[9], pWscControl->WscProfile.Profile[0].Key[10], pWscControl->WscProfile.Profile[0].Key[11], pWscControl->WscProfile.Profile[0].Key[12], pWscControl->WscProfile.Profile[0].Key[13], pWscControl->WscProfile.Profile[0].Key[14], pWscControl->WscProfile.Profile[0].Key[15])); P2pPerstTabInsert(pAdapter, pEntry->Addr, &pWscControl->WscProfile.Profile[0]); // this is a persistent connection. pAdapter->P2pCfg.ExtListenInterval = P2P_EXT_LISTEN_INTERVAL; pAdapter->P2pCfg.ExtListenPeriod = P2P_EXT_LISTEN_PERIOD; } } #endif //P2P_SUPPORT // pWscControl->EapMsgRunning = FALSE; } break; default: DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : Unsupported Msg Type\n")); if (WscData) os_free_mem(NULL, WscData); return; } if(OpCode > WSC_OPCODE_UPNP_MASK) bUPnPStatus = WscSendUPnPMessage(pAdapter, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_NORMAL, WscData, DataLen, Elem->TimeStamp.u.LowPart, Elem->TimeStamp.u.HighPart, &pWscControl->EntryAddr[0], CurOpMode); else if(OpCode > 0 && OpCode < WSC_OPCODE_UPNP_MASK) { #ifdef WSC_V2_SUPPORT pWscControl->WscTxBufLen = 0; pWscControl->pWscCurBufIdx = NULL; pWscControl->bWscLastOne = TRUE; if (pWscControl->bWscFragment && (DataLen > pWscControl->WscFragSize)) { ASSERT(DataLen < MGMT_DMA_BUFFER_SIZE); NdisMoveMemory(pWscControl->pWscTxBuf, WscData, DataLen); pWscControl->WscTxBufLen = DataLen; NdisZeroMemory(WscData, DataLen); pWscControl->bWscLastOne = FALSE; pWscControl->bWscFirstOne = TRUE; NdisMoveMemory(WscData, pWscControl->pWscTxBuf, pWscControl->WscFragSize); DataLen = pWscControl->WscFragSize; pWscControl->WscTxBufLen -= pWscControl->WscFragSize; pWscControl->pWscCurBufIdx = (pWscControl->pWscTxBuf + pWscControl->WscFragSize); } #endif /* WSC_V2_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (pWscControl->WscState != WSC_STATE_CONFIGURED) WscSendMessage(pAdapter, OpCode, WscData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (ADHOC_ON(pAdapter)) WscSendMessage(pAdapter, OpCode, WscData, DataLen, pWscControl, STA_MODE, EAP_CODE_REQ); else WscSendMessage(pAdapter, OpCode, WscData, DataLen, pWscControl, STA_MODE, EAP_CODE_RSP); } #endif /* CONFIG_STA_SUPPORT */ } else bUPnPStatus = TRUE; if(bUPnPMsg) { if(pWscControl->WscState == WSC_STATE_SENT_M2D) { /*After M2D, reset the status of State Machine. */ pWscControl->WscState = WSC_STATE_WAIT_UPNP_START; pWscUPnPInfo->bUPnPInProgress = FALSE; } } Fail: DBGPRINT(RT_DEBUG_TRACE, ("WscEapRegistrarAction : rv = %d\n", rv)); if (rv) { if (rv <= WSC_ERROR_DEV_PWD_AUTH_FAIL) { pWscControl->RegData.SelfInfo.ConfigError = rv; } else if ((rv == WSC_ERROR_HASH_FAIL) || (rv == WSC_ERROR_HMAC_FAIL)) pWscControl->RegData.SelfInfo.ConfigError = WSC_ERROR_DECRYPT_CRC_FAIL; switch(rv) { case WSC_ERROR_HASH_FAIL: pWscControl->WscStatus = STATUS_WSC_ERROR_HASH_FAIL; break; case WSC_ERROR_HMAC_FAIL: pWscControl->WscStatus = STATUS_WSC_ERROR_HMAC_FAIL; break; default: pWscControl->WscStatus = STATUS_WSC_FAIL; break; } RTMPSendWirelessEvent(pAdapter, IW_WSC_STATUS_FAIL, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); if (bUPnPMsg) { if (pWscUPnPInfo->bUPnPMsgTimerRunning == TRUE) { RTMPCancelTimer(&pWscUPnPInfo->UPnPMsgTimer, &Cancelled); pWscUPnPInfo->bUPnPMsgTimerRunning = FALSE; } pWscUPnPInfo->bUPnPInProgress = FALSE; } else { DataLen = BuildMessageNACK(pAdapter, pWscControl, WscData); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { WscSendMessage(pAdapter, WSC_OPCODE_NACK, WscData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ); pEntry->bWscCapable = FALSE; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (ADHOC_ON(pAdapter)) WscSendMessage(pAdapter, WSC_OPCODE_NACK, WscData, DataLen, pWscControl, STA_MODE, EAP_CODE_REQ); else WscSendMessage(pAdapter, WSC_OPCODE_NACK, WscData, DataLen, pWscControl, STA_MODE, EAP_CODE_RSP); } #endif /* CONFIG_STA_SUPPORT */ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); pWscControl->EapolTimerRunning = FALSE; } /* If a PIN authentication or communication error occurs after sending message M6, the Registrar MUST warn the user and MUST NOT automatically reuse the PIN. Furthermore, if the Registrar detects this situation and prompts the user for a new PIN from the Enrollee device, it MUST NOT accept the same PIN again without warning the user of a potential attack. */ if (pWscControl->WscState >= WSC_STATE_WAIT_M7) { pWscControl->WscRejectSamePinFromEnrollee = TRUE; pWscControl->WscPinCode = 0; } pWscControl->WscState = WSC_STATE_OFF; pWscControl->WscStatus = STATUS_WSC_IDLE; /*NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); */ /*pWscControl->WscMode = 1; */ bUPnPStatus = FALSE; } if(WscData) os_free_mem(NULL, WscData); if(bUPnPMsg && (bUPnPStatus == FALSE)) WscUPnPErrHandle(pAdapter, pWscControl, Elem->TimeStamp.u.LowPart); if (pWscControl->WscState == WSC_STATE_CONFIGURED) { #ifdef WSC_LED_SUPPORT UCHAR WPSLEDStatus; #endif /* WSC_LED_SUPPORT */ pWscControl->bWscTrigger = FALSE; #ifdef IWSC_SUPPORT if ((pAdapter->OpMode == OPMODE_STA) && (pAdapter->StaCfg.BssType == BSS_ADHOC)) { if (pAdapter->StaCfg.IWscInfo.bSinglePIN) { pAdapter->StaCfg.IWscInfo.bDoNotStop = TRUE; } else pAdapter->StaCfg.IWscInfo.bDoNotStop = FALSE; RTMP_SEM_LOCK(&pWscControl->WscConfiguredPeerListSemLock); WscInsertPeerEntryByMAC(&pWscControl->WscConfiguredPeerList, pWscControl->WscPeerMAC); RTMP_SEM_UNLOCK(&pWscControl->WscConfiguredPeerListSemLock); NdisZeroMemory(pWscControl->WscPeerMAC, MAC_ADDR_LEN); // We need to clear here for 4-way handshaking MlmeEnqueue(pAdapter, IWSC_STATE_MACHINE, IWSC_MT2_MLME_STOP, 0, NULL, 0); RTMP_MLME_HANDLER(pAdapter); } #endif /* IWSC_SUPPORT */ if (pWscControl->Wsc2MinsTimerRunning) { pWscControl->Wsc2MinsTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled); } if (bUPnPMsg) { if (pWscUPnPInfo->bUPnPMsgTimerRunning == TRUE) { RTMPCancelTimer(&pWscUPnPInfo->UPnPMsgTimer, &Cancelled); pWscUPnPInfo->bUPnPMsgTimerRunning = FALSE; } pWscUPnPInfo->bUPnPInProgress = FALSE; pWscUPnPInfo->registrarID = 0; } #ifdef CONFIG_AP_SUPPORT else { if (CurOpMode == AP_MODE) { WscBuildBeaconIE(pAdapter, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, pEntry->apidx, NULL, 0, CurOpMode); WscBuildProbeRespIE(pAdapter, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, pWscControl->EntryIfIdx, NULL, 0, CurOpMode); APUpdateBeaconFrame(pAdapter, pEntry->apidx); } } NdisZeroMemory(&pAdapter->CommonCfg.WscStaPbcProbeInfo, sizeof(WSC_STA_PBC_PROBE_INFO)); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { #ifdef IWSC_SUPPORT if (pAdapter->StaCfg.IWscInfo.bDoNotStop == FALSE) #endif /* IWSC_SUPPORT */ pWscControl->WscConfMode = WSC_DISABLE; if (pAdapter->StaCfg.BssType == BSS_INFRA) pWscControl->WscState = WSC_STATE_WAIT_EAPFAIL; } #endif /* CONFIG_STA_SUPPORT */ if (INFRA_ON(pAdapter) || ( (pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED) && ((CurOpMode == AP_MODE) || (ADHOC_ON(pAdapter))) ) ) { pWscControl->WscConfStatus = WSC_SCSTATE_CONFIGURED; #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { { /* Use ApplyProfileIdx to inform WscUpdatePortCfgTimer AP acts registrar. */ pWscControl->WscProfile.ApplyProfileIdx |= 0x8000; RTMPSetTimer(&pWscControl->WscUpdatePortCfgTimer, 1000); pWscControl->WscUpdatePortCfgTimerRunning = TRUE; } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pAdapter->StaCfg.bAutoConnectByBssid = TRUE; if ((pWscControl->bConfiguredAP) #ifdef WSC_V2_SUPPORT /* Check AP is v2 or v1, Check WscV2 Enabled or not */ && !(pWscControl->WscV2Info.bForceSetAP && pWscControl->WscV2Info.bEnableWpsV2 && (pWscControl->RegData.PeerInfo.Version2!= 0)) #endif /* WSC_V2_SUPPORT */ ) RTMPMoveMemory(&pWscControl->WscProfile, &pWscControl->WscM7Profile, sizeof(pWscControl->WscM7Profile)); WscWriteConfToPortCfg(pAdapter, pWscControl, &pWscControl->WscProfile.Profile[0], TRUE); { /*#ifdef KTHREAD_SUPPORT */ /* WAKE_UP(&(pAdapter->wscTask)); */ /*#else */ /* RTMP_SEM_EVENT_UP(&(pAdapter->wscTask.taskSema)); */ /*#endif */ RtmpOsTaskWakeUp(&(pAdapter->wscTask)); } #ifdef IWSC_SUPPORT if (pAdapter->StaCfg.BssType == BSS_ADHOC) { if (pAdapter->StaCfg.IWscInfo.bDoNotStop == FALSE) { WscBuildBeaconIE(pAdapter, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, BSS0, NULL, 0, STA_MODE); WscBuildProbeRespIE(pAdapter, WSC_MSGTYPE_REGISTRAR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, BSS0, NULL, 0, STA_MODE); } pAdapter->StaCfg.IWscInfo.bReStart = TRUE; WscLinkDown(pAdapter); if (pAdapter->StaCfg.IWscInfo.bIWscDevQueryReqTimerRunning == FALSE) { pAdapter->StaCfg.IWscInfo.bIWscDevQueryReqTimerRunning = TRUE; RTMPSetTimer(&pAdapter->StaCfg.IWscInfo.IWscDevQueryTimer, 200); } } #endif /* IWSC_SUPPORT */ } #endif /* CONFIG_STA_SUPPORT */ } #ifdef WSC_LED_SUPPORT /* The protocol is finished. */ WPSLEDStatus = LED_WPS_SUCCESS; RTMPSetLED(pAdapter, WPSLEDStatus); #endif /* WSC_LED_SUPPORT */ #ifdef IWSC_SUPPORT if (pAdapter->StaCfg.IWscInfo.bDoNotStop == FALSE) #endif /* IWSC_SUPPORT */ { pWscControl->WscPinCode = 0; pWscControl->WscMode = 1; } RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); pWscControl->EapolTimerRunning = FALSE; #ifdef IWSC_SUPPORT /* Some peer doesn't stop beacon and send de-auth, it will cause 4-way failed when our MAC is higher than peer. After WPS process complete, delete entry here for adding entry to table again for 4-way handshaking. */ if (pEntry && (pAdapter->StaCfg.BssType == BSS_ADHOC)) MacTableDeleteEntry(pAdapter, pEntry->Aid, pEntry->Addr); #endif /* IWSC_SUPPORT */ return; } } VOID WscTimeOutProcess( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN INT nWscState, IN PWSC_CTRL pWscControl) { INT WscMode; UCHAR CurOpMode = 0xFF; #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) CurOpMode = AP_MODE; #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif // CONFIG_STA_SUPPORT // if (nWscState == WSC_STATE_WAIT_ACK) pWscControl->WscState = WSC_STATE_CONFIGURED; else if (nWscState == WSC_STATE_WAIT_RESP_ID) pWscControl->WscState = WSC_STATE_OFF; else if (nWscState == WSC_STATE_RX_M2D) { pWscControl->WscState = WSC_STATE_FAIL; #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (pEntry && IS_ENTRY_CLIENT(pEntry)) { WscSendEapFail(pAd, pWscControl, TRUE); } #ifdef APCLI_SUPPORT if (pEntry && IS_ENTRY_APCLI(pEntry)) { WscApCliLinkDown(pAd, pWscControl); } #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ pWscControl->EapolTimerRunning = FALSE; pWscControl->WscRetryCount = 0; #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { WscLinkDown(pAd); } #endif /* CONFIG_STA_SUPPORT */ return; } else if (nWscState == WSC_STATE_WAIT_EAPFAIL) { pWscControl->WscState = WSC_STATE_OFF; pWscControl->WscStatus = STATUS_WSC_CONFIGURED; pWscControl->WscConfMode = WSC_DISABLE; } else { #ifdef CONFIG_AP_SUPPORT if ((pWscControl->WscActionMode == WSC_PROXY) && (pAd->OpMode == OPMODE_AP)) { pWscControl->WscState = WSC_STATE_OFF; } else #endif /* CONFIG_AP_SUPPORT */ pWscControl->WscState = WSC_STATE_FAIL; } if (nWscState == WSC_STATE_WAIT_M8) pWscControl->bWscTrigger = FALSE; pWscControl->WscRetryCount = 0; NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); pWscControl->EapolTimerRunning = FALSE; if (pWscControl->WscMode == 1) WscMode = DEV_PASS_ID_PIN; else WscMode = DEV_PASS_ID_PBC; #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if ((pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED) && ((nWscState == WSC_STATE_WAIT_DONE) || (nWscState == WSC_STATE_WAIT_ACK))) { pWscControl->bWscTrigger = FALSE; pWscControl->WscConfStatus = WSC_SCSTATE_CONFIGURED; WscBuildBeaconIE(pAd, pWscControl->WscConfStatus, FALSE, WscMode, pWscControl->WscConfigMethods, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode); WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, pWscControl->WscConfStatus, FALSE, WscMode, pWscControl->WscConfigMethods, pWscControl->EntryIfIdx, NULL, 0, CurOpMode); pAd->WriteWscCfgToDatFile = pWscControl->EntryIfIdx; WscWriteConfToPortCfg(pAd, pWscControl, &pWscControl->WscProfile.Profile[0], FALSE); #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx & MIN_NET_DEVICE_FOR_P2P_GO) { P2P_GoStop(pAd); P2P_GoStartUp(pAd, MAIN_MBSSID); } else #endif /* P2P_SUPPORT */ { APStop(pAd); APStartUp(pAd); } /*#ifdef KTHREAD_SUPPORT */ /* WAKE_UP(&(pAd->wscTask)); */ /*#else */ /* RTMP_SEM_EVENT_UP(&(pAd->wscTask.taskSema)); */ /*#endif */ RtmpOsTaskWakeUp(&(pAd->wscTask)); } else { if (pEntry && IS_ENTRY_CLIENT(pEntry)) { pEntry->bWscCapable = FALSE; WscSendEapFail(pAd, pWscControl, TRUE); } WscBuildBeaconIE(pAd, pWscControl->WscConfStatus, FALSE, WscMode, pWscControl->WscConfigMethods, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode); WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, pWscControl->WscConfStatus, FALSE, WscMode, pWscControl->WscConfigMethods, pWscControl->EntryIfIdx, NULL, 0, CurOpMode); } #ifdef APCLI_SUPPORT if (pEntry && IS_ENTRY_APCLI(pEntry)) { WscApCliLinkDown(pAd, pWscControl); } #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { WscLinkDown(pAd); } #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("WscTimeOutProcess\n")); } VOID WscEAPOLTimeOutAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PUCHAR WscData = NULL; PMAC_TABLE_ENTRY pEntry = NULL; PWSC_CTRL pWscControl = NULL; PRTMP_ADAPTER pAd = NULL; UINT MaxWscDataLen = WSC_MAX_DATA_LEN; UCHAR CurOpMode = 0xFF; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscEAPOLTimeOutAction\n")); if (FunctionContext == 0) { return; } else { pWscControl = (PWSC_CTRL)FunctionContext; pAd = (PRTMP_ADAPTER)pWscControl->pAd; if (pAd == NULL) { return; } pEntry = MacTableLookup(pWscControl->pAd, pWscControl->EntryAddr); } #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) CurOpMode = AP_MODE; #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif // CONFIG_STA_SUPPORT // if ((CurOpMode == AP_MODE) || ADHOC_ON(pAd)) { if (pEntry == NULL) { #ifdef CONFIG_AP_SUPPORT /* Some WPS Client will send dis-assoc close to WSC_DONE. If AP misses WSC_DONE, WPS Client still sends dis-assoc to AP. AP driver needs to check wsc_state here for considering WPS process with this client is completed. */ if ((CurOpMode == AP_MODE) && ((pWscControl->WscState == WSC_STATE_WAIT_DONE) || (pWscControl->WscState == WSC_STATE_WAIT_ACK))) { pWscControl->WscStatus = STATUS_WSC_CONFIGURED; pWscControl->bWscTrigger = FALSE; if (pWscControl->Wsc2MinsTimerRunning) { BOOLEAN Cancelled; pWscControl->Wsc2MinsTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled); } WscTimeOutProcess(pAd, NULL, pWscControl->WscState, pWscControl); } #endif /* CONFIG_AP_SUPPORT */ #ifdef IWSC_SUPPORT #ifdef CONFIG_STA_SUPPORT if ((pAd->OpMode == OPMODE_STA) && (pAd->StaCfg.BssType == BSS_ADHOC) && (pAd->StaCfg.WscControl.WscConfMode == WSC_ENROLLEE)) pAd->StaCfg.IWscInfo.bReStart = TRUE; #endif // CONFIG_STA_SUPPORT // #endif // IWSC_SUPPORT // pWscControl->EapolTimerRunning = FALSE; NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); DBGPRINT(RT_DEBUG_TRACE, ("sta is left.\n")); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLTimeOutAction\n")); return; } } if (!pWscControl->EapolTimerRunning) { pWscControl->WscRetryCount = 0; goto out; } if (pWscControl->EapolTimerPending) { RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); DBGPRINT(RT_DEBUG_TRACE, ("EapolTimer Pending......\n")); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLTimeOutAction\n")); return; } #ifdef WSC_V2_SUPPORT MaxWscDataLen = MaxWscDataLen + (UINT)pWscControl->WscV2Info.ExtraTlv.TlvLen; #endif /* WSC_V2_SUPPORT */ os_alloc_mem(NULL, (UCHAR **)&WscData, MaxWscDataLen); /* if ((WscData = kmalloc(WSC_MAX_DATA_LEN, GFP_ATOMIC))!= NULL) */ if (WscData != NULL) NdisZeroMemory(WscData, WSC_MAX_DATA_LEN); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (pEntry && IS_ENTRY_CLIENT(pEntry) && (pWscControl->WscState <= WSC_STATE_CONFIGURED) && (pWscControl->WscActionMode != WSC_PROXY)) { /* A timer in the AP should cause to be disconnected after 5 seconds if a */ /* valid EAP-Rsp/Identity indicating WPS is not received. */ /* << from WPS EAPoL and RSN handling.doc >> */ WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_RESP_ID, pWscControl); /* If do disassocation here, it will affect connection of non-WPS clients. */ goto out; } } #endif /* CONFIG_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("WscState = %d\n", pWscControl->WscState)); switch(pWscControl->WscState) { case WSC_STATE_WAIT_REQ_ID: /* For IWSC case, keep sending EAPOL_START until 2 mins timeout */ if ((pWscControl->WscRetryCount >= 2) #ifdef CONFIG_STA_SUPPORT && (pAd->StaCfg.BssType == BSS_INFRA) #endif /* CONFIG_STA_SUPPORT */ ) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_REQ_ID, pWscControl); else { pWscControl->WscRetryCount++; #ifdef CONFIG_STA_SUPPORT if ((pAd->StaCfg.BssType == BSS_INFRA) && (CurOpMode == STA_MODE)) WscSendEapolStart(pAd, pAd->CommonCfg.Bssid, CurOpMode); else #endif /* CONFIG_STA_SUPPORT */ WscSendEapolStart(pAd, pEntry->Addr, CurOpMode); RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_WAIT_WSC_START: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_WSC_START, pWscControl); else { pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_WAIT_M1: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M1, pWscControl); else { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) WscSendMessage(pWscControl->pAd, WSC_OPCODE_START, NULL, 0, pWscControl, AP_MODE, EAP_CODE_REQ); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { /*WscSendMessage(pWscControl->pAd, WSC_OPCODE_START, NULL, 0, pWscControl, STA_MODE, EAP_CODE_REQ); */ WscSendEapRspId(pAd, pEntry, pWscControl); } #endif /* CONFIG_STA_SUPPORT */ pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_SENT_M1: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M2, pWscControl); else { if (pWscControl->WscActionMode == WSC_ENROLLEE) { { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (IS_ENTRY_CLIENT(pEntry)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ); else if (IS_ENTRY_APCLI(pEntry)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_RSP); #endif /* CONFIG_STA_SUPPORT */ } } pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_RX_M2D: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_RX_M2D, pWscControl); else { pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_WAIT_PIN: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_PIN, pWscControl); else { pWscControl->WscRetryCount++; DBGPRINT(RT_DEBUG_TRACE, ("No PIN CODE, cannot send M2 out!\n")); RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_WAIT_M3: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M3, pWscControl); else { if (pWscControl->WscActionMode == WSC_REGISTRAR) { { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (ADHOC_ON(pAd)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_REQ); else WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_RSP); } #endif /* CONFIG_STA_SUPPORT */ } } pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_WAIT_M4: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M4, pWscControl); else { if (pWscControl->WscActionMode == WSC_ENROLLEE) { { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (IS_ENTRY_CLIENT(pEntry)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ); else if (IS_ENTRY_APCLI(pEntry)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_RSP); #endif /* CONFIG_STA_SUPPORT */ } } pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_WAIT_M5: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M5, pWscControl); else { if (pWscControl->WscActionMode == WSC_REGISTRAR) { { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (ADHOC_ON(pAd)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_REQ); else WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_RSP); } #endif /* CONFIG_STA_SUPPORT */ } } pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_WAIT_M6: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M6, pWscControl); else { if (pWscControl->WscActionMode == WSC_ENROLLEE) { { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (IS_ENTRY_CLIENT(pEntry)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ); else if (IS_ENTRY_APCLI(pEntry)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_RSP); #endif /* CONFIG_STA_SUPPORT */ } } pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_WAIT_M7: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M7, pWscControl); else { if (pWscControl->WscActionMode == WSC_REGISTRAR) { { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (ADHOC_ON(pAd)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_REQ); else WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_RSP); } #endif /* CONFIG_STA_SUPPORT */ } } pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_WAIT_M8: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_M8, pWscControl); else { if (pWscControl->WscActionMode == WSC_ENROLLEE) { { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (IS_ENTRY_CLIENT(pEntry)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ); else if (IS_ENTRY_APCLI(pEntry)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_RSP); #endif /* CONFIG_STA_SUPPORT */ } } pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; case WSC_STATE_WAIT_DONE: if (pWscControl->WscRetryCount >= 2) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_DONE, pWscControl); else { if (pWscControl->WscActionMode == WSC_REGISTRAR) { { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, AP_MODE, EAP_CODE_REQ); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (ADHOC_ON(pAd)) WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_REQ); else WscSendMessage(pWscControl->pAd, WSC_OPCODE_MSG, pWscControl->RegData.LastTx.Data, pWscControl->RegData.LastTx.Length, pWscControl, STA_MODE, EAP_CODE_RSP); } #endif /* CONFIG_STA_SUPPORT */ } } pWscControl->WscRetryCount++; RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_MSG_TIME_OUT); } break; #ifdef CONFIG_AP_SUPPORT /* Only AP_Enrollee needs to wait EAP_ACK */ case WSC_STATE_WAIT_ACK: WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_ACK, pWscControl); break; #endif /* CONFIG_AP_SUPPORT */ case WSC_STATE_WAIT_EAPFAIL: /* Wait 2 seconds */ if (pWscControl->WscRetryCount >= 1) WscTimeOutProcess(pWscControl->pAd, pEntry, WSC_STATE_WAIT_EAPFAIL, pWscControl); else { RTMPModTimer(&pWscControl->EapolTimer, WSC_EAP_EAP_FAIL_TIME_OUT); pWscControl->WscRetryCount++; } break; default: break; } out: if (WscData) os_free_mem(NULL, WscData); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscEAPOLTimeOutAction\n")); } VOID Wsc2MinsTimeOutAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext; PRTMP_ADAPTER pAd = NULL; #ifdef CONFIG_AP_SUPPORT INT IsAPConfigured = 0; #endif /* CONFIG_AP_SUPPORT */ BOOLEAN Cancelled; UCHAR CurOpMode = 0xFF; DBGPRINT(RT_DEBUG_TRACE, ("-----> Wsc2MinsTimeOutAction\n")); if (pWscControl != NULL) { pAd = (PRTMP_ADAPTER)pWscControl->pAd; if (pAd == NULL) { DBGPRINT(RT_DEBUG_TRACE, ("pAd is NULL!\n")); DBGPRINT(RT_DEBUG_TRACE, ("<----- Wsc2MinsTimeOutAction\n")); return; } #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) CurOpMode = AP_MODE; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("Wsc2MinsTimerRunning is %s\n", pWscControl->Wsc2MinsTimerRunning ? "TRUE, reset WscState to WSC_STATE_OFF":"FALSE")); #ifdef WSC_LED_SUPPORT /* 120 seconds WPS walk time expiration. */ pWscControl->bWPSWalkTimeExpiration = TRUE; #endif /* WSC_LED_SUPPORT */ if (pWscControl->Wsc2MinsTimerRunning) { pWscControl->bWscTrigger = FALSE; pWscControl->EapolTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { IsAPConfigured = pWscControl->WscConfStatus; if ((pWscControl->EntryIfIdx & 0x0F) < pAd->ApCfg.BssidNum) { WscBuildBeaconIE(pWscControl->pAd, IsAPConfigured, FALSE, 0, 0, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, CurOpMode); WscBuildProbeRespIE(pWscControl->pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, FALSE, 0, 0, pWscControl->EntryIfIdx, NULL, 0, CurOpMode); APUpdateBeaconFrame(pWscControl->pAd, pWscControl->EntryIfIdx & 0x0F); } if ((pWscControl->WscConfMode & WSC_PROXY) == 0) { /* Proxy mechanism is disabled */ pWscControl->WscState = WSC_STATE_OFF; } } #endif /* CONFIG_AP_SUPPORT */ pWscControl->WscMode = 1; pWscControl->WscRetryCount = 0; pWscControl->Wsc2MinsTimerRunning = FALSE; pWscControl->WscSelReg = 0; pWscControl->WscStatus = STATUS_WSC_IDLE; RTMPSendWirelessEvent(pAd, IW_WSC_2MINS_TIMEOUT, NULL, (pWscControl->EntryIfIdx & 0x0F), 0); if (pWscControl->WscScanTimerRunning) { pWscControl->WscScanTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscScanTimer, &Cancelled); } if (pWscControl->WscPBCTimerRunning) { pWscControl->WscPBCTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscPBCTimer, &Cancelled); } #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pAd->StaCfg.bAutoConnectByBssid = FALSE; RTMPZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID); pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen; RTMPMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); if (INFRA_ON(pAd) || (pWscControl->WscConfMode == WSC_ENROLLEE)) WscLinkDown(pAd); else { AsicDisableSync(pAd); WscBuildBeaconIE(pAd, pWscControl->WscConfStatus, FALSE, 0, 0, BSS0, NULL, 0, CurOpMode); WscBuildProbeRespIE(pAd, WSC_MSGTYPE_REGISTRAR, pWscControl->WscConfStatus, FALSE, 0, 0, BSS0, NULL, 0, CurOpMode); MakeIbssBeacon(pAd); AsicEnableIbssSync(pAd); } pWscControl->WscConfMode = WSC_DISABLE; pWscControl->WscState = WSC_STATE_OFF; } #endif /* CONFIG_STA_SUPPORT */ } #ifdef WSC_LED_SUPPORT /* if link is up, there shall be nothing wrong */ /* perhaps we will set another flag to do it */ if ((OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) && (pWscControl->WscState == WSC_STATE_OFF) && (pWscControl->WscStatus == STATUS_WSC_CONFIGURED)) { DBGPRINT(RT_DEBUG_TRACE, ("WscConnectTimeout --> Connection OK\n")); } else { UCHAR WPSLEDStatus; pWscControl->WscStatus = STATUS_WSC_FAIL; pWscControl->WscState = WSC_STATE_OFF; /* WPS LED mode 7, 8, 11 or 12. */ if ((LED_MODE(pAd) == WPS_LED_MODE_7) || (LED_MODE(pAd) == WPS_LED_MODE_8) || (LED_MODE(pAd) == WPS_LED_MODE_11) || (LED_MODE(pAd) == WPS_LED_MODE_12)) { pWscControl->bSkipWPSTurnOffLED = FALSE; /* Turn off the WPS LED modoe due to the maximum WPS processing time is expired (120 seconds). */ WPSLEDStatus = LED_WPS_TURN_LED_OFF; RTMPSetLED(pAd, WPSLEDStatus); } else if ((LED_MODE(pAd) == WPS_LED_MODE_9) /* WPS LED mode 9. */ ) { if (pWscControl->WscMode == WSC_PIN_MODE) /* PIN method. */ { /* The NIC using PIN method fails to finish the WPS handshaking within 120 seconds. */ WPSLEDStatus = LED_WPS_ERROR; RTMPSetLED(pAd, WPSLEDStatus); /* Turn off the WPS LED after 15 seconds. */ RTMPSetTimer(&pWscControl->WscLEDTimer, WSC_WPS_FAIL_LED_PATTERN_TIMEOUT); /* The Ralink UI would make RT_OID_DISCONNECT_REQUEST request while it receive STATUS_WSC_EAP_FAILED. */ /* Allow the NIC to turn off the WPS LED after WSC_WPS_SKIP_TURN_OFF_LED_TIMEOUT seconds. */ pWscControl->bSkipWPSTurnOffLED = TRUE; RTMPSetTimer(&pWscControl->WscSkipTurnOffLEDTimer, WSC_WPS_SKIP_TURN_OFF_LED_TIMEOUT); DBGPRINT(RT_DEBUG_TRACE, ("%s: The NIC using PIN method fails to finish the WPS handshaking within 120 seconds.\n", __FUNCTION__)); } else if (pWscControl->WscMode == WSC_PBC_MODE) /* PBC method. */ { switch (pWscControl->WscLastWarningLEDMode) /* Based on last WPS warning LED mode. */ { case 0: case LED_WPS_ERROR: case LED_WPS_SESSION_OVERLAP_DETECTED: /* Failed to find any partner. */ WPSLEDStatus = LED_WPS_ERROR; RTMPSetLED(pAd, WPSLEDStatus); /* Turn off the WPS LED after 15 seconds. */ RTMPSetTimer(&pWscControl->WscLEDTimer, WSC_WPS_FAIL_LED_PATTERN_TIMEOUT); /* The Ralink UI would make RT_OID_DISCONNECT_REQUEST request while it receive STATUS_WSC_EAP_FAILED. */ /* Allow the NIC to turn off the WPS LED after WSC_WPS_SKIP_TURN_OFF_LED_TIMEOUT seconds. */ pWscControl->bSkipWPSTurnOffLED = TRUE; RTMPSetTimer(&pWscControl->WscSkipTurnOffLEDTimer, WSC_WPS_SKIP_TURN_OFF_LED_TIMEOUT); DBGPRINT(RT_DEBUG_TRACE, ("%s: Last WPS LED status is LED_WPS_ERROR.\n", __FUNCTION__)); break; default: /* do nothing. */ break; } } else { /* do nothing. */ } } else { /* do nothing. */ } DBGPRINT(RT_DEBUG_TRACE, ("WscConnectTimeout --> Fail to connect\n")); } #endif /* WSC_LED_SUPPORT */ } DBGPRINT(RT_DEBUG_TRACE, ("<----- Wsc2MinsTimeOutAction\n")); } /* ======================================================================== Routine Description: Classify EAP message type for enrolee Arguments: pAd - NIC Adapter pointer Elem - The EAP packet Return Value: Received EAP message type IRQL = DISPATCH_LEVEL Note: ======================================================================== */ UCHAR WscRxMsgType( IN PRTMP_ADAPTER pAdapter, IN PMLME_QUEUE_ELEM pElem) { USHORT Length; PUCHAR pData; USHORT WscType, WscLen; STRING id_data[] = {"hello"}; STRING fail_data[] = {"EAP_FAIL"}; STRING wsc_start[] = {"WSC_START"}; #ifdef WSC_V2_SUPPORT STRING wsc_frag_ack[] = "WSC_FRAG_ACK"; #endif /* WSC_V2_SUPPORT */ STRING regIdentity[] = {"WFA-SimpleConfig-Registrar"}; STRING enrIdentity[] = {"WFA-SimpleConfig-Enrollee"}; if (pElem->Msg[0] == 'W' && pElem->Msg[1] == 'F' && pElem->Msg[2] == 'A') { /* Eap-Rsp(Identity) */ if (memcmp(regIdentity, pElem->Msg, strlen(regIdentity)) == 0) return WSC_MSG_EAP_REG_RSP_ID; else if (memcmp(enrIdentity, pElem->Msg, strlen(enrIdentity)) == 0) return WSC_MSG_EAP_ENR_RSP_ID; } else if (NdisEqualMemory(id_data, pElem->Msg, pElem->MsgLen)) { /* Eap-Req/Identity(hello) */ return WSC_MSG_EAP_REQ_ID; } else if (NdisEqualMemory(fail_data, pElem->Msg, pElem->MsgLen)) { /* Eap-Fail */ return WSC_MSG_EAP_FAIL; } else if (NdisEqualMemory(wsc_start, pElem->Msg, pElem->MsgLen)) { /* Eap-Req(Wsc_Start) */ return WSC_MSG_EAP_REQ_START; } #ifdef WSC_V2_SUPPORT else if (NdisEqualMemory(wsc_frag_ack, pElem->Msg, pElem->MsgLen)) { /* WSC FRAG ACK */ return WSC_MSG_EAP_FRAG_ACK; } #endif /* WSC_V2_SUPPORT */ else { /* Eap-Esp(Messages) */ pData = pElem->Msg; Length = (USHORT)pElem->MsgLen; /* the first TLV item in EAP Messages must be WSC_IE_VERSION */ NdisMoveMemory(&WscType, pData, 2); if (ntohs(WscType) != WSC_ID_VERSION) goto out; /* Not Wsc Start, We have to look for WSC_IE_MSG_TYPE to classify M2 ~ M8, the remain size must large than 4 */ while (Length > 4) { /* arm-cpu has packet alignment issue, it's better to use memcpy to retrieve data */ NdisMoveMemory(&WscType, pData, 2); NdisMoveMemory(&WscLen, pData + 2, 2); WscLen = ntohs(WscLen); if (ntohs(WscType) == WSC_ID_MSG_TYPE) { return(*(pData + 4)); /* Found the message type */ } else { pData += (WscLen + 4); Length -= (WscLen + 4); } } } out: return WSC_MSG_UNKNOWN; } /* ======================================================================== Routine Description: Classify WSC message type Arguments: EAPType Value of EAP message type MsgType Internal Message definition for MLME state machine Return Value: TRUE Found appropriate message type FALSE No appropriate message type Note: All these constants are defined in wsc.h For supplicant, there is only EAPOL Key message avaliable ======================================================================== */ BOOLEAN WscMsgTypeSubst( IN UCHAR EAPType, IN UCHAR EAPCode, OUT INT *MsgType) { switch (EAPType) { case EAPPacket: *MsgType = WSC_EAPOL_PACKET_MSG; break; case EAPOLStart: *MsgType = WSC_EAPOL_START_MSG; break; default: DBGPRINT(RT_DEBUG_TRACE, ("WscMsgTypeSubst : unsupported EAP Type(%d); \n", EAPType)); return FALSE; } return TRUE; } VOID WscInitRegistrarPair( IN PRTMP_ADAPTER pAdapter, IN PWSC_CTRL pWscControl, IN UCHAR apidx) { UCHAR CurOpMode = 0xff; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscInitRegistrarPair\n")); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter) CurOpMode = AP_MODE; #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAdapter) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) { CurOpMode = AP_MODE; apidx = MAIN_MBSSID; } #endif /* P2P_SUPPORT */ #endif // CONFIG_STA_SUPPORT // pWscControl->WscActionMode = 0; /* 1. Version */ /*pWscControl->RegData.SelfInfo.Version = WSC_VERSION; */ /* 2. UUID Enrollee, last 6 bytes use MAC */ NdisMoveMemory(&pWscControl->RegData.SelfInfo.Uuid[0], &pWscControl->Wsc_Uuid_E[0], UUID_LEN_HEX); /* 3. MAC address */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (apidx >= HW_BEACON_MAX_NUM) { DBGPRINT(RT_DEBUG_ERROR, ("%s: apidx >= HW_BEACON_MAX_NUM!\n", __FUNCTION__)); apidx = 0; } NdisMoveMemory(pWscControl->RegData.SelfInfo.MacAddr, pAdapter->ApCfg.MBSSID[apidx].Bssid, 6); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) NdisMoveMemory(pWscControl->RegData.SelfInfo.MacAddr, pAdapter->CurrentAddress, 6); #endif /* CONFIG_STA_SUPPORT */ /* 4. Device Name */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (!RTMP_TEST_FLAG(pWscControl, 0x04)) NdisMoveMemory(&pWscControl->RegData.SelfInfo.DeviceName, AP_WSC_DEVICE_NAME, sizeof(AP_WSC_DEVICE_NAME)); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (!RTMP_TEST_FLAG(pWscControl, 0x04)) { NdisMoveMemory(&pWscControl->RegData.SelfInfo.DeviceName, STA_WSC_DEVICE_NAME, sizeof(STA_WSC_DEVICE_NAME)); } } #endif /* CONFIG_STA_SUPPORT */ /* 5. Manufacture woody */ if (!RTMP_TEST_FLAG(pWscControl, 0x01)) NdisMoveMemory(&pWscControl->RegData.SelfInfo.Manufacturer, WSC_MANUFACTURE, sizeof(WSC_MANUFACTURE)); /* 6. Model Name */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (!RTMP_TEST_FLAG(pWscControl, 0x02)) NdisMoveMemory(&pWscControl->RegData.SelfInfo.ModelName, AP_WSC_MODEL_NAME, sizeof(AP_WSC_MODEL_NAME)); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (!RTMP_TEST_FLAG(pWscControl, 0x02)) { NdisMoveMemory(&pWscControl->RegData.SelfInfo.ModelName, STA_WSC_MODEL_NAME, sizeof(STA_WSC_MODEL_NAME)); } } #endif /* CONFIG_STA_SUPPORT */ /* 7. Model Number */ if (!RTMP_TEST_FLAG(pWscControl, 0x08)) NdisMoveMemory(&pWscControl->RegData.SelfInfo.ModelNumber, WSC_MODEL_NUMBER, sizeof(WSC_MODEL_NUMBER)); /* 8. Serial Number */ if (!RTMP_TEST_FLAG(pWscControl, 0x10)) NdisMoveMemory(&pWscControl->RegData.SelfInfo.SerialNumber, WSC_MODEL_SERIAL, sizeof(WSC_MODEL_SERIAL)); /* 9. Authentication Type Flags */ /* Open(=1), WPAPSK(=2),Shared(=4), WPA2PSK(=20),WPA(=8),WPA2(=10) */ /* (0x01 | 0x02 | 0x04 | 0x20 | 0x08 | 0x10) = 0x3F */ /* WCN vista logo will check this flags. */ #ifdef WSC_V2_SUPPORT if (pWscControl->WscV2Info.bEnableWpsV2) /* AuthTypeFlags only needs to include Open and WPA2PSK in WSC 2.0. */ pWscControl->RegData.SelfInfo.AuthTypeFlags = cpu2be16(0x0021); else #endif /* WSC_V2_SUPPORT */ pWscControl->RegData.SelfInfo.AuthTypeFlags = cpu2be16(0x003F); /* 10. Encryption Type Flags */ /* None(=1), WEP(=2), TKIP(=4), AES(=8) */ /* (0x01 | 0x02 | 0x04 | 0x08) = 0x0F */ #ifdef WSC_V2_SUPPORT if (pWscControl->WscV2Info.bEnableWpsV2) /* EncrTypeFlags only needs to include None and AES in WSC 2.0. */ pWscControl->RegData.SelfInfo.EncrTypeFlags = cpu2be16(0x0009); else #endif /* WSC_V2_SUPPORT */ pWscControl->RegData.SelfInfo.EncrTypeFlags = cpu2be16(0x000F); /* 11. Connection Type Flag */ pWscControl->RegData.SelfInfo.ConnTypeFlags = 0x01; /* ESS */ /* 12. Associate state */ pWscControl->RegData.SelfInfo.AssocState = cpu2be16(0x0000); /* Not associated */ /* 13. Configure Error */ pWscControl->RegData.SelfInfo.ConfigError = cpu2be16(0x0000); /* No error */ /* 14. OS Version */ pWscControl->RegData.SelfInfo.OsVersion = cpu2be32(0x80000000); /* first bit must be 1 */ /* 15. RF Band */ /* Some WPS AP would check RfBand value in M1, ex. D-Link DIR-628 */ pWscControl->RegData.SelfInfo.RfBand = 0x00; if (WMODE_CAP_5G(pAdapter->CommonCfg.PhyMode)) pWscControl->RegData.SelfInfo.RfBand |= WSC_RFBAND_50GHZ; /* 5.0G */ if (WMODE_CAP_2G(pAdapter->CommonCfg.PhyMode)) pWscControl->RegData.SelfInfo.RfBand |= WSC_RFBAND_24GHZ; /* 2.4G */ /* 16. Config Method */ pWscControl->RegData.SelfInfo.ConfigMethods = cpu2be16(pWscControl->WscConfigMethods); /*pWscControl->RegData.EnrolleeInfo.ConfigMethods = cpu2be16(WSC_CONFIG_METHODS); // Label, Display, PBC */ /*pWscControl->RegData.EnrolleeInfo.ConfigMethods = cpu2be16(0x0084); // Label, Display, PBC */ /* 17. Simple Config State */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) pWscControl->RegData.SelfInfo.ScState = pWscControl->WscConfStatus; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) pWscControl->RegData.SelfInfo.ScState = 0x01; #endif /* CONFIG_STA_SUPPORT */ /* 18. Device Password ID */ if (pWscControl->WscMode == WSC_PIN_MODE) { #ifdef IWSC_SUPPORT if ((pAdapter->StaCfg.BssType == BSS_ADHOC) && (pAdapter->StaCfg.IWscInfo.bLimitedUI == FALSE)) { pWscControl->RegData.SelfInfo.DevPwdId = cpu2be16(DEV_PASS_ID_REG); /* PIN mode */ } else #endif /* IWSC_SUPPORT */ pWscControl->RegData.SelfInfo.DevPwdId = cpu2be16(DEV_PASS_ID_PIN); /* PIN mode */ } #ifdef IWSC_SUPPORT else if (pWscControl->WscMode == WSC_SMPBC_MODE) { pWscControl->RegData.SelfInfo.DevPwdId = cpu2be16(DEV_PASS_ID_SMPBC); // SMPBC mode } #endif // IWSC_SUPPORT // else { pWscControl->RegData.SelfInfo.DevPwdId = cpu2be16(DEV_PASS_ID_PBC); /* PBC */ } /* 19. SSID */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) NdisMoveMemory(pWscControl->RegData.SelfInfo.Ssid, pAdapter->ApCfg.MBSSID[apidx].Ssid, pAdapter->ApCfg.MBSSID[apidx].SsidLen); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) NdisMoveMemory(pWscControl->RegData.SelfInfo.Ssid, pAdapter->CommonCfg.Ssid, pAdapter->CommonCfg.SsidLen); #endif /* CONFIG_STA_SUPPORT */ /* 20. Primary Device Type */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx >= MIN_NET_DEVICE_FOR_P2P_CLI) { NdisMoveMemory(&pWscControl->RegData.SelfInfo.PriDeviceType, pAdapter->P2pCfg.DevInfo.PriDeviceType, 8); } else #endif /* P2P_SUPPORT */ if (pWscControl->EntryIfIdx & MIN_NET_DEVICE_FOR_APCLI) NdisMoveMemory(&pWscControl->RegData.SelfInfo.PriDeviceType, &STA_Wsc_Pri_Dev_Type[0], 8); else NdisMoveMemory(&pWscControl->RegData.SelfInfo.PriDeviceType, &AP_Wsc_Pri_Dev_Type[0], 8); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) NdisMoveMemory(&pWscControl->RegData.SelfInfo.PriDeviceType, &STA_Wsc_Pri_Dev_Type[0], 8); #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscInitRegistrarPair\n")); } VOID WscSendEapReqId( IN PRTMP_ADAPTER pAd, IN PMAC_TABLE_ENTRY pEntry, IN UCHAR CurOpMode) { UCHAR Header802_3[14]; USHORT Length; IEEE8021X_FRAME Ieee_8021x; EAP_FRAME EapFrame; UCHAR *pOutBuffer = NULL; ULONG FrameLen = 0; UCHAR Data[] = "hello"; UCHAR Id; PWSC_CTRL pWpsCtrl = NULL; NdisZeroMemory(Header802_3,sizeof(UCHAR)*14); /* 1. Send EAP-Rsp Id */ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendEapReqId\n")); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { pWpsCtrl = &pAd->ApCfg.MBSSID[pEntry->apidx].WscControl; MAKE_802_3_HEADER(Header802_3, &pEntry->Addr[0], &pAd->ApCfg.MBSSID[pEntry->apidx].Bssid[0], EAPOL); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pWpsCtrl = &pAd->StaCfg.WscControl; MAKE_802_3_HEADER(Header802_3, &pEntry->Addr[0], &pAd->CurrentAddress[0], EAPOL); } #endif /* CONFIG_STA_SUPPORT */ if (pWpsCtrl == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("pWpsCtrl == NULL!\n")); return; } /* Length, -1 NULL pointer of string */ Length = sizeof(EAP_FRAME) + sizeof(Data) - 1; /* Zero 802.1x body */ NdisZeroMemory(&Ieee_8021x, sizeof(Ieee_8021x)); Ieee_8021x.Version = EAPOL_VER; Ieee_8021x.Type = EAPPacket; Ieee_8021x.Length = cpu2be16(Length); /* Zero EAP frame */ NdisZeroMemory(&EapFrame, sizeof(EapFrame)); /* RFC 3748 Ch 4.1: recommended to initalize Identifier with a * random number */ Id = RandomByte(pAd); if (Id == pWpsCtrl->lastId) Id += 1; EapFrame.Code = EAP_CODE_REQ; EapFrame.Id = Id; EapFrame.Length = cpu2be16(Length); EapFrame.Type = EAP_TYPE_ID; pWpsCtrl->lastId = Id; /* Out buffer for transmitting EAP-Req(Identity) */ /* pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); */ os_alloc_mem(NULL, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER); if(pOutBuffer == NULL) return; FrameLen = 0; /* Make Transmitting frame */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(IEEE8021X_FRAME), &Ieee_8021x, sizeof(EapFrame), &EapFrame, (sizeof(Data) - 1), Data, END_OF_ARGS); /* Copy frame to Tx ring */ RTMPToWirelessSta(pAd, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)pOutBuffer, FrameLen, TRUE); pWpsCtrl->WscRetryCount = 0; if (pOutBuffer) /* kfree(pOutBuffer); */ os_free_mem(NULL, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendEapReqId\n")); } /* ======================================================================== Routine Description: Send EAPoL-Start packet to AP. Arguments: pAd - NIC Adapter pointer Return Value: None IRQL = DISPATCH_LEVEL Note: Actions after link up 1. Change the correct parameters 2. Send EAPOL - START ======================================================================== */ VOID WscSendEapolStart( IN PRTMP_ADAPTER pAdapter, IN PUCHAR pBssid, IN UCHAR CurOpMode) { IEEE8021X_FRAME Packet; UCHAR Header802_3[14]; MAC_TABLE_ENTRY *pEntry; pEntry = MacTableLookup(pAdapter, pBssid); #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (pAdapter->StaCfg.WscControl.WscState >= WSC_STATE_WAIT_WSC_START) return; } #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendEapolStart\n")); NdisZeroMemory(Header802_3,sizeof(UCHAR)*14); /* 1. Change the authentication to open and encryption to none if necessary. */ /* init 802.3 header and Fill Packet */ #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (CurOpMode == AP_MODE) { MAKE_802_3_HEADER(Header802_3, pBssid, &pAdapter->ApCfg.ApCliTab[0].CurrentAddress[0], EAPOL); } #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) MAKE_802_3_HEADER(Header802_3, pBssid, &pAdapter->CurrentAddress[0], EAPOL); #endif /* CONFIG_STA_SUPPORT */ /* Zero message 2 body */ NdisZeroMemory(&Packet, sizeof(Packet)); Packet.Version = EAPOL_VER; Packet.Type = EAPOLStart; Packet.Length = cpu2be16(0); if (pEntry) RTMPToWirelessSta(pAdapter, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)&Packet, 4, TRUE); #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (CurOpMode == AP_MODE) { /* Update WSC status */ pAdapter->ApCfg.ApCliTab[0].WscControl.WscStatus = STATUS_WSC_EAPOL_START_SENT; pAdapter->ApCfg.ApCliTab[0].WscControl.WscState = WSC_STATE_WAIT_REQ_ID; if (!pAdapter->ApCfg.ApCliTab[0].WscControl.EapolTimerRunning) { pAdapter->ApCfg.ApCliTab[0].WscControl.EapolTimerRunning = TRUE; RTMPSetTimer(&pAdapter->ApCfg.ApCliTab[0].WscControl.EapolTimer, WSC_EAPOL_START_TIME_OUT); } } #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { /* Update WSC status */ pAdapter->StaCfg.WscControl.WscStatus = STATUS_WSC_EAPOL_START_SENT; pAdapter->StaCfg.WscControl.WscState = WSC_STATE_WAIT_REQ_ID; if (!pAdapter->StaCfg.WscControl.EapolTimerRunning) { pAdapter->StaCfg.WscControl.EapolTimerRunning = TRUE; RTMPSetTimer(&pAdapter->StaCfg.WscControl.EapolTimer, 2000); } } #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendEapolStart\n")); } VOID WscSendEapRspId( IN PRTMP_ADAPTER pAdapter, IN PMAC_TABLE_ENTRY pEntry, IN PWSC_CTRL pWscControl) { UCHAR Header802_3[14]; USHORT Length = 0; IEEE8021X_FRAME Ieee_8021x; EAP_FRAME EapFrame; UCHAR *pOutBuffer = NULL; ULONG FrameLen = 0; UCHAR regIdentity[] = "WFA-SimpleConfig-Registrar-1-0"; UCHAR enrIdentity[] = "WFA-SimpleConfig-Enrollee-1-0"; UCHAR CurOpMode = 0xff; NdisZeroMemory(Header802_3,sizeof(UCHAR)*14); /* 1. Send EAP-Rsp Id */ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendEapRspId\n")); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter) CurOpMode = AP_MODE; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAdapter) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (CurOpMode == AP_MODE) { MAKE_802_3_HEADER(Header802_3, &pEntry->Addr[0], &pAdapter->ApCfg.ApCliTab[0].CurrentAddress[0], EAPOL); Length = sizeof(EAP_FRAME) + sizeof(enrIdentity) - 1; pWscControl->WscConfMode = WSC_ENROLLEE; /* Ap Client only support Enrollee now. 20070518 */ } #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { /* init 802.3 header and Fill Packet */ if (INFRA_ON(pAdapter)) { MAKE_802_3_HEADER(Header802_3, &pAdapter->CommonCfg.Bssid[0], &pAdapter->CurrentAddress[0], EAPOL); } else { MAKE_802_3_HEADER(Header802_3, &pWscControl->WscPeerMAC[0], &pAdapter->CurrentAddress[0], EAPOL); } /* Length, -1 NULL pointer of string */ if (pWscControl->WscConfMode == WSC_ENROLLEE) Length = sizeof(EAP_FRAME) + sizeof(enrIdentity) - 1; else if (pWscControl->WscConfMode == WSC_REGISTRAR) Length = sizeof(EAP_FRAME) + sizeof(regIdentity) - 1; } #endif /* CONFIG_STA_SUPPORT */ /* Zero 802.1x body */ NdisZeroMemory(&Ieee_8021x, sizeof(Ieee_8021x)); Ieee_8021x.Version = EAPOL_VER; Ieee_8021x.Type = EAPPacket; Ieee_8021x.Length = cpu2be16(Length); /* Zero EAP frame */ NdisZeroMemory(&EapFrame, sizeof(EapFrame)); EapFrame.Code = EAP_CODE_RSP; EapFrame.Id = pWscControl->lastId; EapFrame.Length = cpu2be16(Length); EapFrame.Type = EAP_TYPE_ID; /* Out buffer for transmitting EAP-Req(Identity) */ /* pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); */ os_alloc_mem(NULL, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER); if(pOutBuffer == NULL) return; FrameLen = 0; if (pWscControl->WscConfMode == WSC_REGISTRAR) { /* Make Transmitting frame */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(IEEE8021X_FRAME), &Ieee_8021x, sizeof(EapFrame), &EapFrame, (sizeof(regIdentity) - 1), regIdentity, END_OF_ARGS); } else if (pWscControl->WscConfMode == WSC_ENROLLEE) { #ifdef IWSC_SUPPORT if (pAdapter->StaCfg.BssType == BSS_ADHOC) pWscControl->WscConfStatus = WSC_SCSTATE_UNCONFIGURED; #endif /* IWSC_SUPPORT */ /* Make Transmitting frame */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(IEEE8021X_FRAME), &Ieee_8021x, sizeof(EapFrame), &EapFrame, (sizeof(enrIdentity) - 1), enrIdentity, END_OF_ARGS); } else { DBGPRINT(RT_DEBUG_TRACE, ("WscConfMode(%d) is not WSC_REGISTRAR nor WSC_ENROLLEE.\n", pWscControl->WscConfMode)); goto out; } /* Copy frame to Tx ring */ #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT if (CurOpMode == AP_MODE) { RTMPToWirelessSta(pAdapter, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)pOutBuffer, FrameLen, TRUE); } #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) RTMPToWirelessSta((PRTMP_ADAPTER)pWscControl->pAd, &pAdapter->MacTab.Content[BSSID_WCID], Header802_3, LENGTH_802_3, (PUCHAR)pOutBuffer, FrameLen, TRUE); #endif /* CONFIG_STA_SUPPORT */ pWscControl->WscRetryCount = 0; if (!pWscControl->EapolTimerRunning) { pWscControl->EapolTimerRunning = TRUE; RTMPSetTimer(&pWscControl->EapolTimer, WSC_EAP_ID_TIME_OUT); } out: if (pOutBuffer) /* kfree(pOutBuffer); */ os_free_mem(NULL, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendEapRspId\n")); } VOID WscUPnPErrHandle( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl, IN UINT eventID) { int dataLen; UCHAR *pWscData; UCHAR CurOpMode; DBGPRINT(RT_DEBUG_TRACE, ("Into WscUPnPErrHandle, send WSC_OPCODE_UPNP_CTRL with eventID=0x%x!\n", eventID)); #ifdef P2P_SUPPORT return; #endif /* P2P_SUPPORT */ #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) CurOpMode = AP_MODE; #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif // CONFIG_STA_SUPPORT // os_alloc_mem(NULL, (UCHAR **)&pWscData, WSC_MAX_DATA_LEN); if (pWscData != NULL) { NdisZeroMemory(pWscData, WSC_MAX_DATA_LEN); dataLen = BuildMessageNACK(pAd, pWscControl, pWscData); WscSendUPnPMessage(pAd, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_DATA, WSC_UPNP_DATA_SUB_NORMAL, pWscData, dataLen, eventID, 0, NULL, CurOpMode); os_free_mem(NULL, pWscData); } else { WscSendUPnPMessage(pAd, (pWscControl->EntryIfIdx & 0x0F), WSC_OPCODE_UPNP_CTRL, 0, NULL, 0, eventID, 0, NULL, CurOpMode); } } /* Format of iwcustom msg WSC clientJoin message: 1. SSID which station want to probe(32 bytes): *If the length if SSID string is small than 32 bytes, fill 0x0 for remaining bytes. 2. sender MAC address(6 bytes): 3. Status: Set as 1 means change APStatus as 1. Set as 2 means change STAStatus as 1. Set as 3 means trigger msg. 32 6 1 +----------+--------+------+ |SSIDString| SrcMAC |Status| */ int WscSendUPnPConfReqMsg( IN PRTMP_ADAPTER pAd, IN UCHAR apIdx, IN PUCHAR ssidStr, IN PUCHAR macAddr, IN INT Status, IN UINT eventID, IN UCHAR CurOpMode) { UCHAR pData[39] = {0}; #ifdef P2P_SUPPORT if (apIdx >= MIN_NET_DEVICE_FOR_P2P_CLI) return 0; #endif /* P2P_SUPPORT */ strncpy((PSTRING) pData, (PSTRING)ssidStr, strlen((PSTRING) ssidStr)); NdisMoveMemory(&pData[32], macAddr, MAC_ADDR_LEN); pData[38] = Status; WscSendUPnPMessage(pAd, apIdx, WSC_OPCODE_UPNP_MGMT, WSC_UPNP_MGMT_SUB_CONFIG_REQ, &pData[0], 39, eventID, 0, NULL, CurOpMode); return 0; } /* NETLINK tunnel msg format send to WSCUPnP handler in user space: 1. Signature of following string(Not include the quote, 8 bytes) "RAWSCMSG" 2. eID: eventID (4 bytes) the ID of this message(4 bytes) 3. aID: ackID (4 bytes) means that which event ID this mesage was response to. 4. TL: Message Total Length (4 bytes) Total length of this message. 5. F: Flag (2 bytes) used to notify some specific character of this msg segment. Bit 1: fragment set as 1 if netlink layer have more segment of this Msg need to send. Bit 2~15: reserve, should set as 0 now. 5. SL: Segment Length(2 bytes) msg actual length in this segment, The SL may not equal the "TL" field if "F" ==1 6. devMac: device mac address(6 bytes) Indicate the netdevice which this msg belong. For the wscd in user space will depends this address dispatch the msg to correct UPnP Device instance to handle it. 7. "WSC_MSG" info: 8 4 4 4 2 2 6 variable length(MAXIMUM=232) +------------+----+----+----+--+--+------+------------------------+ | Signature |eID |aID | TL | F | SL|devMac| WSC_MSG | */ int WscSendUPnPMessage( IN PRTMP_ADAPTER pAd, IN UCHAR devIfIdx, IN USHORT msgType, IN USHORT msgSubType, IN PUCHAR pData, IN INT dataLen, IN UINT eventID, IN UINT toIPAddr, IN PUCHAR pMACAddr, IN UCHAR CurOpMode) { /* union iwreq_data wrqu; */ RTMP_WSC_NLMSG_HDR *pNLMsgHdr; RTMP_WSC_MSG_HDR *pWscMsgHdr; UCHAR hdrBuf[42]; /*RTMP_WSC_NLMSG_HDR_LEN + RTMP_WSC_MSG_HDR_LEN */ int totalLen, leftLen, copyLen; PUCHAR pBuf = NULL, pBufPtr = NULL, pPos = NULL; PUCHAR pDevAddr = NULL; #ifdef CONFIG_AP_SUPPORT UCHAR bssIdx = devIfIdx; #endif /* CONFIG_AP_SUPPORT */ ULONG Now; #ifdef P2P_SUPPORT if (devIfIdx >= MIN_NET_DEVICE_FOR_P2P_CLI) return 0; #endif /* P2P_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendUPnPMessage\n")); if ((msgType & WSC_OPCODE_UPNP_MASK) != WSC_OPCODE_UPNP_MASK) return FALSE; #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { #ifdef APCLI_SUPPORT if (devIfIdx & MIN_NET_DEVICE_FOR_APCLI) { bssIdx &= (~MIN_NET_DEVICE_FOR_APCLI); if (bssIdx >= MAX_APCLI_NUM) return FALSE; pDevAddr = &pAd->ApCfg.ApCliTab[bssIdx].CurrentAddress[0]; } else #endif /* APCLI_SUPPORT */ pDevAddr = &pAd->ApCfg.MBSSID[bssIdx].Bssid[0]; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pDevAddr = &pAd->CurrentAddress[0]; } #endif /* CONFIG_STA_SUPPORT */ if (pDevAddr == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("pDevAddr == NULL!\n")); return FALSE; } /*Prepare the NLMsg header */ memset(hdrBuf, 0, sizeof(hdrBuf)); pNLMsgHdr = (RTMP_WSC_NLMSG_HDR *)hdrBuf; memcpy(pNLMsgHdr, WSC_MSG_SIGNATURE, RTMP_WSC_NLMSG_SIGNATURE_LEN); NdisGetSystemUpTime(&Now); pNLMsgHdr->envID = Now; pNLMsgHdr->ackID = eventID; pNLMsgHdr->msgLen = dataLen + RTMP_WSC_MSG_HDR_LEN; /* In order to support multiple wscd, we need this new field to notify the wscd which interface this msg send from. */ NdisMoveMemory(&pNLMsgHdr->devAddr[0], pDevAddr, MAC_ADDR_LEN); /*Prepare the WscMsg header */ pWscMsgHdr = (RTMP_WSC_MSG_HDR *)(hdrBuf + sizeof(RTMP_WSC_NLMSG_HDR)); switch(msgType) { case WSC_OPCODE_UPNP_DATA: pWscMsgHdr->msgType = WSC_OPCODE_UPNP_DATA; break; case WSC_OPCODE_UPNP_MGMT: pWscMsgHdr->msgType = WSC_OPCODE_UPNP_MGMT; break; case WSC_OPCODE_UPNP_CTRL: pWscMsgHdr->msgType = WSC_OPCODE_UPNP_CTRL; break; default: return FALSE; } pWscMsgHdr->msgSubType = msgSubType; pWscMsgHdr->ipAddr = toIPAddr; pWscMsgHdr->msgLen = dataLen; if ((pWscMsgHdr->msgType == WSC_OPCODE_UPNP_DATA) && (eventID == 0) && (pMACAddr != NULL) && (NdisEqualMemory(pMACAddr, ZERO_MAC_ADDR, MAC_ADDR_LEN) == FALSE)) { pWscMsgHdr->msgSubType |= WSC_UPNP_DATA_SUB_INCLUDE_MAC; pNLMsgHdr->msgLen += MAC_ADDR_LEN; pWscMsgHdr->msgLen += MAC_ADDR_LEN; } /*Allocate memory and copy the msg. */ totalLen = leftLen = pNLMsgHdr->msgLen; pPos = pData; os_alloc_mem(NULL, (UCHAR **)&pBuf, IWEVCUSTOM_MSG_MAX_LEN); /* if((pBuf = kmalloc(IWEVCUSTOM_MSG_MAX_LEN, GFP_ATOMIC)) != NULL) */ if (pBuf != NULL) { int firstSeg = 1; while(leftLen) { /*Prepare the payload */ memset(pBuf, 0, IWEVCUSTOM_MSG_MAX_LEN); pNLMsgHdr->segLen = (leftLen > IWEVCUSTOM_PAYLOD_MAX_LEN ? IWEVCUSTOM_PAYLOD_MAX_LEN : leftLen); leftLen -= pNLMsgHdr->segLen; pNLMsgHdr->flags = (leftLen > 0 ? 1 : 0); memcpy(pBuf, pNLMsgHdr, RTMP_WSC_NLMSG_HDR_LEN); pBufPtr = &pBuf[RTMP_WSC_NLMSG_HDR_LEN]; if(firstSeg){ memcpy(pBufPtr, pWscMsgHdr, RTMP_WSC_MSG_HDR_LEN); pBufPtr += RTMP_WSC_MSG_HDR_LEN; copyLen = (pNLMsgHdr->segLen - RTMP_WSC_MSG_HDR_LEN); if ((pWscMsgHdr->msgSubType & WSC_UPNP_DATA_SUB_INCLUDE_MAC) == WSC_UPNP_DATA_SUB_INCLUDE_MAC) { NdisMoveMemory(pBufPtr, pMACAddr, MAC_ADDR_LEN); pBufPtr += MAC_ADDR_LEN; copyLen -= MAC_ADDR_LEN; } NdisMoveMemory(pBufPtr, pPos, copyLen); pPos += copyLen; firstSeg = 0; } else { NdisMoveMemory(pBufPtr, pPos, pNLMsgHdr->segLen); pPos += pNLMsgHdr->segLen; } /*Send WSC Msg to wscd, msg length = pNLMsgHdr->segLen + sizeof(RTMP_WSC_NLMSG_HDR) */ RtmpOSWrielessEventSend(pAd->net_dev, RT_WLAN_EVENT_CUSTOM, RT_WSC_UPNP_EVENT_FLAG, NULL, pBuf, pNLMsgHdr->segLen + sizeof(RTMP_WSC_NLMSG_HDR)); } /* kfree(pBuf); */ os_free_mem(NULL, pBuf); } DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendUPnPMessage\n")); return TRUE; } VOID WscSendMessage( IN PRTMP_ADAPTER pAdapter, IN UCHAR OpCode, IN PUCHAR pData, IN INT Len, IN PWSC_CTRL pWscControl, IN UCHAR OpMode, IN UCHAR EapType) { /* Inb-EAP Message */ UCHAR Header802_3[14]; USHORT Length, MsgLen; IEEE8021X_FRAME Ieee_8021x; EAP_FRAME EapFrame; WSC_FRAME WscFrame; UCHAR *pOutBuffer = NULL; ULONG FrameLen = 0; MAC_TABLE_ENTRY *pEntry; #ifdef CONFIG_AP_SUPPORT UCHAR bssIdx = (pWscControl->EntryIfIdx & 0x0F); #endif /* CONFIG_AP_SUPPORT */ UCHAR CurOpMode = 0xFF; if ((Len <= 0) && (OpCode != WSC_OPCODE_START) && (OpCode != WSC_OPCODE_FRAG_ACK)) return; /* Send message */ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendMessage\n")); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter) CurOpMode = AP_MODE; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAdapter) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ NdisZeroMemory(Header802_3,sizeof(UCHAR)*14); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (OpMode == AP_MODE) { MAKE_802_3_HEADER(Header802_3, &pWscControl->EntryAddr[0], &pAdapter->ApCfg.MBSSID[bssIdx].Bssid[0], EAPOL); } #ifdef APCLI_SUPPORT else if (OpMode == AP_CLIENT_MODE) { MAKE_802_3_HEADER(Header802_3, &pWscControl->EntryAddr[0], &pAdapter->ApCfg.ApCliTab[0].CurrentAddress[0], EAPOL); } #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (OpMode == STA_MODE) { if (INFRA_ON(pAdapter)) { MAKE_802_3_HEADER(Header802_3, &pAdapter->CommonCfg.Bssid[0], &pAdapter->CurrentAddress[0], EAPOL); } else { MAKE_802_3_HEADER(Header802_3, &pWscControl->EntryAddr[0], &pAdapter->CurrentAddress[0], EAPOL); } } } #endif /* CONFIG_STA_SUPPORT */ /* Length = EAP + WSC_Frame + Payload */ Length = sizeof(EAP_FRAME) + sizeof(WSC_FRAME) + Len; if (pWscControl->bWscFragment && (pWscControl->bWscFirstOne)) { Length += 2; MsgLen = pWscControl->WscTxBufLen + Len; MsgLen = htons(MsgLen); } /* Zero 802.1x body */ NdisZeroMemory(&Ieee_8021x, sizeof(Ieee_8021x)); Ieee_8021x.Version = EAPOL_VER; Ieee_8021x.Type = EAPPacket; Ieee_8021x.Length = cpu2be16(Length); /* Zero EAP frame */ NdisZeroMemory(&EapFrame, sizeof(EapFrame)); if (EapType == EAP_CODE_REQ) { EapFrame.Code = EAP_CODE_REQ; EapFrame.Id = ++(pWscControl->lastId); } else { EapFrame.Code = EAP_CODE_RSP; EapFrame.Id = pWscControl->lastId; /* same as eap_req id */ } EapFrame.Length = cpu2be16(Length); EapFrame.Type = EAP_TYPE_WSC; /* Zero WSC Frame */ NdisZeroMemory(&WscFrame, sizeof(WscFrame)); WscFrame.SMI[0] = 0x00; WscFrame.SMI[1] = 0x37; WscFrame.SMI[2] = 0x2A; WscFrame.VendorType = cpu2be32(WSC_VENDOR_TYPE); WscFrame.OpCode = OpCode; WscFrame.Flags = 0x00; if (pWscControl->bWscFragment && (pWscControl->bWscLastOne == FALSE)) WscFrame.Flags |= WSC_MSG_FLAG_MF; if (pWscControl->bWscFragment && (pWscControl->bWscFirstOne)) { WscFrame.Flags |= WSC_MSG_FLAG_LF; } /* Out buffer for transmitting message */ os_alloc_mem(NULL, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER); if(pOutBuffer == NULL) return; FrameLen = 0; /* Make Transmitting frame */ if (pData && (Len > 0)) { if (pWscControl->bWscFragment && (pWscControl->bWscFirstOne)) { UCHAR LF_Len = 2; ULONG TmpLen = 0; pWscControl->bWscFirstOne = FALSE; MakeOutgoingFrame(pOutBuffer, &TmpLen, sizeof(IEEE8021X_FRAME), &Ieee_8021x, sizeof(EapFrame), &EapFrame, sizeof(WscFrame), &WscFrame, LF_Len, &MsgLen, END_OF_ARGS); FrameLen += TmpLen; MakeOutgoingFrame(pOutBuffer + FrameLen, &TmpLen, Len, pData, END_OF_ARGS); FrameLen += TmpLen; } else { MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(IEEE8021X_FRAME), &Ieee_8021x, sizeof(EapFrame), &EapFrame, sizeof(WscFrame), &WscFrame, Len, pData, END_OF_ARGS); } } else MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(IEEE8021X_FRAME), &Ieee_8021x, sizeof(EapFrame), &EapFrame, sizeof(WscFrame), &WscFrame, END_OF_ARGS); /* Copy frame to Tx ring */ pEntry = MacTableLookup(pAdapter, &pWscControl->EntryAddr[0]); if (pEntry) RTMPToWirelessSta(pAdapter, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)pOutBuffer, FrameLen, TRUE); else DBGPRINT(RT_DEBUG_WARN, ("pEntry is NULL\n")); if (pOutBuffer) os_free_mem(NULL, pOutBuffer); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendMessage\n")); } VOID WscBuildBeaconIE( IN PRTMP_ADAPTER pAd, IN UCHAR b_configured, IN BOOLEAN b_selRegistrar, IN USHORT devPwdId, IN USHORT selRegCfgMethods, IN UCHAR apidx, IN UCHAR *pAuthorizedMACs, IN UCHAR AuthorizedMACsLen, IN UCHAR CurOpMode) { WSC_IE_HEADER ieHdr; /* UCHAR Data[256]; */ UCHAR *Data = NULL; PUCHAR pData; INT Len = 0, templen = 0; USHORT tempVal = 0; PWSC_CTRL pWpsCtrl = NULL; PWSC_REG_DATA pReg = NULL; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&Data, 256); if (Data == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) pWpsCtrl = &pAd->ApCfg.MBSSID[apidx & 0x0F].WscControl; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) pWpsCtrl = &pAd->StaCfg.WscControl; #endif /* CONFIG_STA_SUPPORT */ pReg = &pWpsCtrl->RegData; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscBuildBeaconIE\n")); /* WSC IE HEader */ ieHdr.elemId = 221; ieHdr.length = 4; ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50; ieHdr.oui[2] = 0xF2; #ifdef IWSC_SUPPORT if ((CurOpMode == STA_MODE) && (pAd->StaCfg.BssType == BSS_ADHOC)) ieHdr.oui[3] = 0x10; else #endif /* IWSC_SUPPORT */ ieHdr.oui[3] = 0x04; pData = (PUCHAR) &Data[0]; Len = 0; /* 1. Version */ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0); pData += templen; Len += templen; /* 2. Simple Config State */ templen = AppendWSCTLV(WSC_ID_SC_STATE, pData, (UINT8 *)&b_configured, 0); pData += templen; Len += templen; #ifdef CONFIG_AP_SUPPORT #ifdef WSC_V2_SUPPORT if ((CurOpMode == AP_MODE) && pWpsCtrl->bSetupLock) { // AP Setup Lock templen = AppendWSCTLV(WSC_ID_AP_SETUP_LOCKED, pData, (UINT8 *)&pWpsCtrl->bSetupLock, 0); pData += templen; Len += templen; } #endif /* WSC_V2_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ if ( b_selRegistrar ) { /* 3.Selected Registrar */ templen = AppendWSCTLV(WSC_ID_SEL_REGISTRAR, pData, (UINT8 *)&b_selRegistrar, 0); pData += templen; Len += templen; /*4. Device Password ID */ tempVal = htons(devPwdId); templen = AppendWSCTLV(WSC_ID_DEVICE_PWD_ID, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; /* 5. Selected Registrar Config Methods */ tempVal = selRegCfgMethods; #ifdef IWSC_SUPPORT if (CurOpMode == STA_MODE) { if (pAd->StaCfg.WscControl.WscMode == WSC_PIN_MODE) { tempVal &= 0x200F; } else { tempVal &= 0x02F0; } if (pAd->StaCfg.IWscInfo.bLimitedUI) { tempVal &= (~WSC_CONFMET_KEYPAD); } else { tempVal |= WSC_CONFMET_KEYPAD; } } #endif /* IWSC_SUPPORT */ tempVal = htons(tempVal); templen = AppendWSCTLV(WSC_ID_SEL_REG_CFG_METHODS, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; } /* 6. UUID last 6 bytes use MAC */ templen = AppendWSCTLV(WSC_ID_UUID_E, pData, &pWpsCtrl->Wsc_Uuid_E[0], 0); pData += templen; Len += templen; /* 7. RF Bands */ if (CurOpMode == AP_MODE) { if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) tempVal = 2; else tempVal = 1; } else { if (pAd->CommonCfg.Channel > 14) tempVal = 2; else tempVal = 1; } #ifdef RT_BIG_ENDIAN tempVal =SWAP16(tempVal); #endif /* RT_BIG_ENDIAN */ templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; #ifdef IWSC_SUPPORT if ((pAd->StaCfg.BssType == BSS_ADHOC) && (CurOpMode == STA_MODE)) { UCHAR respType; // Connection Type Flag ESS templen = AppendWSCTLV(WSC_ID_CONN_TYPE, pData, (UINT8 *)&pReg->SelfInfo.ConnTypeFlags, 0); pData += templen; Len += templen; #ifdef IWSC_TEST_SUPPORT /* This modification is for Broadcom test bed. Broadcom test bed use same buffer to record IWSC IE from Beacon and Probe Response. But the content of IWSC IE in Beacon is different from Probe Response. */ if ((pWpsCtrl->WscMode == WSC_SMPBC_MODE) && (pWpsCtrl->WscConfMode == WSC_REGISTRAR)) { BOOLEAN bEntryAcceptable = FALSE; BOOLEAN bRegistrationReady = TRUE; PIWSC_INFO pIWscInfo = NULL; pIWscInfo = &pAd->StaCfg.IWscInfo; if (pIWscInfo->bIWscEntryTimerRunning) bEntryAcceptable = TRUE; /* Entry Acceptable (only for IBSS) */ templen = AppendWSCTLV(WSC_ID_ENTRY_ACCEPTABLE, pData, (UINT8 *)&bEntryAcceptable, 0); pData += templen; Len += templen; if (pWpsCtrl->EapMsgRunning) bRegistrationReady = FALSE; /* Registration Ready (only for IBSS) */ templen = AppendWSCTLV(WSC_ID_REGISTRATON_READY, pData, (UINT8 *)&bRegistrationReady, 0); pData += templen; Len += templen; } #endif /* IWSC_TEST_SUPPORT */ /* IWSC IP Address Configuration */ tempVal = htons(pAd->StaCfg.IWscInfo.IpConfMethod); templen = AppendWSCTLV(WSC_ID_IP_ADDR_CONF_METHOD, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; #ifdef IWSC_TEST_SUPPORT /* This modification is for Broadcom test bed. Broadcom test bed use same buffer to record IWSC IE from Beacon and Probe Response. But the content of IWSC IE in Beacon is different from Probe Response. */ /* Response Type WSC_ID_RESP_TYPE */ if (pAd->StaCfg.WscControl.WscConfMode == WSC_REGISTRAR) respType = WSC_MSGTYPE_REGISTRAR; else respType = WSC_MSGTYPE_ENROLLEE_OPEN_8021X; templen = AppendWSCTLV(WSC_ID_RESP_TYPE, pData, (UINT8 *)&respType, 0); pData += templen; Len += templen; #endif /* IWSC_TEST_SUPPORT */ } #endif /* IWSC_SUPPORT */ #ifdef WSC_V2_SUPPORT if (pWpsCtrl->WscV2Info.bEnableWpsV2) { PWSC_TLV pWscTLV = &pWpsCtrl->WscV2Info.ExtraTlv; WscGenV2Msg(pWpsCtrl, b_selRegistrar, pAuthorizedMACs, AuthorizedMACsLen, &pData, &Len); /* Extra attribute that is not defined in WSC Sepc. */ if (pWscTLV->pTlvData && pWscTLV->TlvLen) { templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen); pData += templen; Len += templen; } } #endif /* WSC_V2_SUPPORT */ #ifdef P2P_SUPPORT // 12. Primary Device Type templen = AppendWSCTLV(WSC_ID_PRIM_DEV_TYPE, pData, pReg->SelfInfo.PriDeviceType, 0); pData += templen; Len += templen; // 13. Device Name NdisZeroMemory(pData, 32 + 4); templen = AppendWSCTLV(WSC_ID_DEVICE_NAME, pData, &pAd->P2pCfg.DeviceName, pAd->P2pCfg.DeviceNameLen); pData += templen; Len += templen; #endif /* P2P_SUPPORT */ ieHdr.length = ieHdr.length + Len; #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { memcpy(pAd->ApCfg.MBSSID[apidx].WscIEBeacon.Value, &ieHdr, sizeof(WSC_IE_HEADER)); memcpy(pAd->ApCfg.MBSSID[apidx].WscIEBeacon.Value + sizeof(WSC_IE_HEADER), Data, Len); pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen = sizeof(WSC_IE_HEADER) + Len; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { memcpy(pAd->StaCfg.WpsIEBeacon.Value, &ieHdr, sizeof(WSC_IE_HEADER)); memcpy(pAd->StaCfg.WpsIEBeacon.Value + sizeof(WSC_IE_HEADER), Data, Len); pAd->StaCfg.WpsIEBeacon.ValueLen = sizeof(WSC_IE_HEADER) + Len; } #endif /* CONFIG_STA_SUPPORT */ if (Data != NULL) os_free_mem(NULL, Data); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscBuildBeaconIE\n")); } VOID WscBuildProbeRespIE( IN PRTMP_ADAPTER pAd, IN UCHAR respType, IN UCHAR scState, IN BOOLEAN b_selRegistrar, IN USHORT devPwdId, IN USHORT selRegCfgMethods, IN UCHAR apidx, IN UCHAR *pAuthorizedMACs, IN INT AuthorizedMACsLen, IN UCHAR CurOpMode) { WSC_IE_HEADER ieHdr; /* UCHAR Data[512]; */ UCHAR *Data = NULL; PUCHAR pData; INT Len = 0, templen = 0; USHORT tempVal = 0; PWSC_CTRL pWpsCtrl = NULL; PWSC_REG_DATA pReg = NULL; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&Data, 512); if (Data == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) pWpsCtrl = &pAd->ApCfg.MBSSID[apidx & 0x0F].WscControl; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) pWpsCtrl = &pAd->StaCfg.WscControl; #endif /* CONFIG_STA_SUPPORT */ pReg = &pWpsCtrl->RegData; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscBuildProbeRespIE, apidx = %x\n", apidx)); /* WSC IE Header */ ieHdr.elemId = 221; ieHdr.length = 4; ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50; ieHdr.oui[2] = 0xF2; #ifdef IWSC_SUPPORT if ((CurOpMode == STA_MODE) && (pAd->StaCfg.BssType == BSS_ADHOC)) ieHdr.oui[3] = 0x10; else #endif /* IWSC_SUPPORT */ ieHdr.oui[3] = 0x04; pData = (PUCHAR) &Data[0]; Len = 0; /* 1. Version */ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0); pData += templen; Len += templen; /* 2. Simple Config State */ templen = AppendWSCTLV(WSC_ID_SC_STATE, pData, (UINT8 *)&scState, 0); pData += templen; Len += templen; #ifdef CONFIG_AP_SUPPORT #ifdef WSC_V2_SUPPORT if ((CurOpMode == AP_MODE) && pWpsCtrl->bSetupLock) { // AP Setup Lock templen = AppendWSCTLV(WSC_ID_AP_SETUP_LOCKED, pData, (UINT8 *)&pWpsCtrl->bSetupLock, 0); pData += templen; Len += templen; } #endif /* WSC_V2_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ if ( b_selRegistrar ) { /* 3. Selected Registrar */ templen = AppendWSCTLV(WSC_ID_SEL_REGISTRAR, pData, (UINT8 *)&b_selRegistrar, 0); pData += templen; Len += templen; /* 4. Device Password ID */ tempVal = htons(devPwdId); templen = AppendWSCTLV(WSC_ID_DEVICE_PWD_ID, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; /* 5. Selected Registrar Config Methods */ #ifdef IWSC_SUPPORT if ((CurOpMode == STA_MODE) && (pAd->StaCfg.IWscInfo.bSelRegStart == FALSE)) { if (pWpsCtrl->WscMode == WSC_PIN_MODE) { selRegCfgMethods &= 0x200F; if (pAd->StaCfg.IWscInfo.bLimitedUI) { selRegCfgMethods &= (~WSC_CONFMET_KEYPAD); } else { selRegCfgMethods |= WSC_CONFMET_KEYPAD; } } else { selRegCfgMethods &= 0x02F0; } } #endif /* IWSC_SUPPORT */ tempVal = htons(selRegCfgMethods); templen = AppendWSCTLV(WSC_ID_SEL_REG_CFG_METHODS, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; #ifdef IWSC_SUPPORT if ((CurOpMode == STA_MODE) && pAd->StaCfg.IWscInfo.bSelRegStart) { templen = AppendWSCTLV(WSC_ID_MAC_ADDR, pData, pAd->StaCfg.IWscInfo.RegMacAddr, 0); pData += templen; Len += templen; pAd->StaCfg.IWscInfo.bSelRegStart = FALSE; } #endif /* IWSC_SUPPORT */ } /* 6. Response Type WSC_ID_RESP_TYPE */ templen = AppendWSCTLV(WSC_ID_RESP_TYPE, pData, (UINT8 *)&respType, 0); pData += templen; Len += templen; /* 7. UUID last 6 bytes use MAC */ templen = AppendWSCTLV(WSC_ID_UUID_E, pData, &pWpsCtrl->Wsc_Uuid_E[0], 0); pData += templen; Len += templen; /* 8. Manufacturer */ NdisZeroMemory(pData, 64 + 4); templen = AppendWSCTLV(WSC_ID_MANUFACTURER, pData, pReg->SelfInfo.Manufacturer, strlen((PSTRING) pReg->SelfInfo.Manufacturer)); pData += templen; Len += templen; /* 9. Model Name */ NdisZeroMemory(pData, 32 + 4); templen = AppendWSCTLV(WSC_ID_MODEL_NAME, pData, pReg->SelfInfo.ModelName, strlen((PSTRING) pReg->SelfInfo.ModelName)); pData += templen; Len += templen; /* 10. Model Number */ NdisZeroMemory(pData, 32 + 4); templen = AppendWSCTLV(WSC_ID_MODEL_NUMBER, pData, pReg->SelfInfo.ModelNumber, strlen((PSTRING) pReg->SelfInfo.ModelNumber)); pData += templen; Len += templen; /* 11. Serial Number */ NdisZeroMemory(pData, 32 + 4); templen = AppendWSCTLV(WSC_ID_SERIAL_NUM, pData, pReg->SelfInfo.SerialNumber, strlen((PSTRING) pReg->SelfInfo.SerialNumber)); pData += templen; Len += templen; /* 12. Primary Device Type */ templen = AppendWSCTLV(WSC_ID_PRIM_DEV_TYPE, pData, pReg->SelfInfo.PriDeviceType, 0); pData += templen; Len += templen; /* 13. Device Name */ NdisZeroMemory(pData, 32 + 4); templen = AppendWSCTLV(WSC_ID_DEVICE_NAME, pData, pReg->SelfInfo.DeviceName, strlen((PSTRING) pReg->SelfInfo.DeviceName)); pData += templen; Len += templen; /* 14. Config Methods */ /*tempVal = htons(0x008a); */ /*tempVal = htons(0x0084); */ #ifdef P2P_SUPPORT /* Some P2P Device will check this config method for PBC. (ex. Samsung GALAXYSII) If this config method doesn't include PBC, some P2P Device doesn't send provision request if we are P2P GO. */ if (apidx >= MIN_NET_DEVICE_FOR_P2P_GO) { if (pAd->P2pCfg.bSigmaEnabled) tempVal = pWpsCtrl->WscConfigMethods & 0xff7f;/* patch p2p sigma 4.2.2 (Version 5.0) */ else tempVal = pWpsCtrl->WscConfigMethods; } else #endif /* P2P_SUPPORT */ { /* WSC 1.0 WCN logo testing will check the value of config method in probe response and M1. Config method shall be identical in probe response and M1. */ #ifdef WSC_V2_SUPPORT if (pWpsCtrl->WscV2Info.bEnableWpsV2) tempVal = pWpsCtrl->WscConfigMethods & 0xF97F; else #endif /* WSC_V2_SUPPORT */ tempVal = pWpsCtrl->WscConfigMethods & 0x00FF; } tempVal = htons(tempVal); templen = AppendWSCTLV(WSC_ID_CONFIG_METHODS, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; /* 15. RF Bands */ if (CurOpMode == AP_MODE) { if (WMODE_CAP_5G(pAd->CommonCfg.PhyMode)) tempVal = 2; else tempVal = 1; } else { if (pAd->CommonCfg.Channel > 14) tempVal = 2; else tempVal = 1; } #ifdef RT_BIG_ENDIAN tempVal =SWAP16(tempVal); #endif /* RT_BIG_ENDIAN */ templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; #ifdef IWSC_SUPPORT if ((pAd->StaCfg.BssType == BSS_ADHOC) && (CurOpMode == STA_MODE)) { /* Connection Type Flag ESS */ templen = AppendWSCTLV(WSC_ID_CONN_TYPE, pData, (UINT8 *)&pReg->SelfInfo.ConnTypeFlags, 0); pData += templen; Len += templen; if ((pWpsCtrl->WscMode == WSC_SMPBC_MODE) && (pWpsCtrl->WscConfMode == WSC_REGISTRAR)) { BOOLEAN bEntryAcceptable = FALSE; BOOLEAN bRegistrationReady = TRUE; PIWSC_INFO pIWscInfo = NULL; pIWscInfo = &pAd->StaCfg.IWscInfo; if (pIWscInfo->bIWscEntryTimerRunning) bEntryAcceptable = TRUE; /* Entry Acceptable (only for IBSS) */ templen = AppendWSCTLV(WSC_ID_ENTRY_ACCEPTABLE, pData, (UINT8 *)&bEntryAcceptable, 0); pData += templen; Len += templen; if (pWpsCtrl->EapMsgRunning) bRegistrationReady = FALSE; /* Registration Ready (only for IBSS) */ templen = AppendWSCTLV(WSC_ID_REGISTRATON_READY, pData, (UINT8 *)&bRegistrationReady, 0); pData += templen; Len += templen; } /* IWSC IP Address Configuration */ tempVal = htons(pAd->StaCfg.IWscInfo.IpConfMethod); templen = AppendWSCTLV(WSC_ID_IP_ADDR_CONF_METHOD, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; } #endif /* IWSC_SUPPORT */ #ifdef WSC_V2_SUPPORT if (pWpsCtrl->WscV2Info.bEnableWpsV2) { PWSC_TLV pWscTLV = &pWpsCtrl->WscV2Info.ExtraTlv; WscGenV2Msg(pWpsCtrl, b_selRegistrar, pAuthorizedMACs, AuthorizedMACsLen, &pData, &Len); /* Extra attribute that is not defined in WSC Sepc. */ if (pWscTLV->pTlvData && pWscTLV->TlvLen) { templen = AppendWSCTLV(pWscTLV->TlvTag, pData, (UINT8 *)pWscTLV->pTlvData, pWscTLV->TlvLen); pData += templen; Len += templen; } } #endif /* WSC_V2_SUPPORT */ if (Len > 251) { DBGPRINT(RT_DEBUG_TRACE, ("Len is overflow!\n")); } ieHdr.length = ieHdr.length + Len; #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { memcpy(pAd->ApCfg.MBSSID[apidx & 0xF].WscIEProbeResp.Value, &ieHdr, sizeof(WSC_IE_HEADER)); memcpy(pAd->ApCfg.MBSSID[apidx & 0xF].WscIEProbeResp.Value + sizeof(WSC_IE_HEADER), Data, Len); pAd->ApCfg.MBSSID[apidx & 0xF].WscIEProbeResp.ValueLen = sizeof(WSC_IE_HEADER) + Len; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { memcpy(pAd->StaCfg.WpsIEProbeResp.Value, &ieHdr, sizeof(WSC_IE_HEADER)); memcpy(pAd->StaCfg.WpsIEProbeResp.Value + sizeof(WSC_IE_HEADER), Data, Len); pAd->StaCfg.WpsIEProbeResp.ValueLen = sizeof(WSC_IE_HEADER) + Len; } #endif /* CONFIG_STA_SUPPORT */ if (Data != NULL) os_free_mem(NULL, Data); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscBuildProbeRespIE\n")); } /* ======================================================================== Routine Description: Ap send EAP-Fail to station Arguments: pAd - NIC Adapter pointer Id - ID between EAP-Req and EAP-Rsp pair pEntry - The Station Entry information Return Value: None ======================================================================== */ VOID WscSendEapFail( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl, IN BOOLEAN bSendDeAuth) { UCHAR Header802_3[14]; USHORT Length; IEEE8021X_FRAME Ieee_8021x; EAP_FRAME EapFrame; UCHAR *pOutBuffer = NULL; ULONG FrameLen = 0; #ifdef CONFIG_AP_SUPPORT UCHAR apidx = (pWscControl->EntryIfIdx & 0x0F); #endif /* CONFIG_AP_SUPPORT */ MAC_TABLE_ENTRY *pEntry; UCHAR CurOpMode = 0xFF; NdisZeroMemory(Header802_3,sizeof(UCHAR)*14); /* 1. Send EAP-Rsp Id */ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscSendEapFail\n")); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) CurOpMode = AP_MODE; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { MAKE_802_3_HEADER(Header802_3, &pWscControl->EntryAddr[0], &pAd->ApCfg.MBSSID[apidx].Bssid[0], EAPOL); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { MAKE_802_3_HEADER(Header802_3, &pWscControl->EntryAddr[0], &pAd->CurrentAddress[0], EAPOL); } #endif /* CONFIG_STA_SUPPORT */ /* Length, -1 type size, Eap-Fail doesn't need Type item */ Length = sizeof(EAP_FRAME) - sizeof(UCHAR); /* Zero 802.1x body */ NdisZeroMemory(&Ieee_8021x, sizeof(Ieee_8021x)); Ieee_8021x.Version = EAPOL_VER; Ieee_8021x.Type = EAPPacket; Ieee_8021x.Length = cpu2be16(Length); /* Zero EAP frame */ NdisZeroMemory(&EapFrame, sizeof(EapFrame)); EapFrame.Code = EAP_CODE_FAIL; EapFrame.Id = pWscControl->lastId; EapFrame.Length = cpu2be16(Length); /* Out buffer for transmitting EAP-Req(Identity) */ /* pOutBuffer = kmalloc(MAX_LEN_OF_MLME_BUFFER, MEM_ALLOC_FLAG); */ os_alloc_mem(NULL, (UCHAR **)&pOutBuffer, MAX_LEN_OF_MLME_BUFFER); if(pOutBuffer == NULL) return; FrameLen = 0; /* Make Transmitting frame */ MakeOutgoingFrame(pOutBuffer, &FrameLen, sizeof(IEEE8021X_FRAME), &Ieee_8021x, sizeof(EapFrame)-1, &EapFrame, END_OF_ARGS); pEntry = MacTableLookup(pAd, &pWscControl->EntryAddr[0]); /* Copy frame to Tx ring */ RTMPToWirelessSta(pAd, pEntry, Header802_3, sizeof(Header802_3), (PUCHAR)pOutBuffer, FrameLen, TRUE); if (pOutBuffer) /* kfree(pOutBuffer); */ os_free_mem(NULL, pOutBuffer); #ifdef CONFIG_AP_SUPPORT if (pEntry && bSendDeAuth && (CurOpMode == AP_MODE)) { MlmeDeAuthAction(pAd, pEntry, REASON_DEAUTH_STA_LEAVING, TRUE); } if (pEntry == NULL) { /* If STA dis-connect un-normally, reset EntryAddr here. */ NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); } #endif /* CONFIG_AP_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscSendEapFail\n")); } #ifdef CONFIG_AP_SUPPORT VOID WscBuildAssocRespIE( IN PRTMP_ADAPTER pAd, IN UCHAR ApIdx, IN UCHAR Reason, OUT PUCHAR pOutBuf, OUT PUCHAR pIeLen) { WSC_IE_HEADER ieHdr; /* UCHAR Data[512] = {0}; */ UCHAR *Data = NULL; PUCHAR pData; INT Len = 0, templen = 0; UINT8 tempVal = 0; PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pAd->ApCfg.MBSSID[ApIdx].WscControl.RegData; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscBuildAssocRespIE\n")); /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&Data, 512); if (Data == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } Data[0] = 0; /* WSC IE Header */ ieHdr.elemId = 221; ieHdr.length = 4; ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50; ieHdr.oui[2] = 0xF2; ieHdr.oui[3] = 0x04; 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_AP_WLAN_MGR; templen = AppendWSCTLV(WSC_ID_RESP_TYPE, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; #ifdef WSC_V2_SUPPORT if (pAd->ApCfg.MBSSID[ApIdx].WscControl.WscV2Info.bEnableWpsV2) { WscGenV2Msg(&pAd->ApCfg.MBSSID[ApIdx].WscControl, FALSE, NULL, 0, &pData, &Len); } #endif /* WSC_V2_SUPPORT */ ieHdr.length = ieHdr.length + Len; NdisMoveMemory(pOutBuf, &ieHdr, sizeof(WSC_IE_HEADER)); NdisMoveMemory(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, ("<----- WscBuildAssocRespIE\n")); } VOID WscSelectedRegistrar( IN PRTMP_ADAPTER pAd, IN PUCHAR pReginfo, IN UINT Length, IN UCHAR apidx) { PUCHAR pData; INT IsAPConfigured; UCHAR wsc_version, wsc_sel_reg = 0; USHORT wsc_dev_pass_id = 0, wsc_sel_reg_conf_mthd = 0; USHORT WscType, WscLen; PUCHAR pAuthorizedMACs = NULL; UCHAR AuthorizedMACsLen = 0; PWSC_CTRL pWscCtrl = &pAd->ApCfg.MBSSID[apidx].WscControl; pData = (PUCHAR)pReginfo; if (Length < 4) { DBGPRINT(RT_DEBUG_TRACE, ("WscSelectedRegistrar --> Unknown IE \n")); return; } hex_dump("WscSelectedRegistrar - Reginfo", pReginfo, Length); while (Length > 4) { /* arm-cpu has packet alignment issue, it's better to use memcpy to retrieve data */ NdisMoveMemory(&WscType, pData, 2); NdisMoveMemory(&WscLen, pData + 2, 2); WscLen = ntohs(WscLen); pData += 4; Length -= 4; switch (ntohs(WscType)) { case WSC_ID_VERSION: wsc_version = *pData; break; case WSC_ID_SEL_REGISTRAR: wsc_sel_reg = *pData; break; case WSC_ID_DEVICE_PWD_ID: NdisMoveMemory(&wsc_dev_pass_id, pData, sizeof(USHORT)); wsc_dev_pass_id = be2cpu16(wsc_dev_pass_id); break; case WSC_ID_SEL_REG_CFG_METHODS: NdisMoveMemory(&wsc_sel_reg_conf_mthd, pData, sizeof(USHORT)); wsc_sel_reg_conf_mthd = be2cpu16(wsc_sel_reg_conf_mthd); break; case WSC_ID_VENDOR_EXT: #ifdef WSC_V2_SUPPORT if (pWscCtrl->WscV2Info.bEnableWpsV2 && (WscLen > 0)) { /* Find WFA_EXT_ID_AUTHORIZEDMACS */ os_alloc_mem(NULL, &pAuthorizedMACs, WscLen); if (pAuthorizedMACs) { NdisZeroMemory(pAuthorizedMACs, WscLen); WscParseV2SubItem(WFA_EXT_ID_AUTHORIZEDMACS, pData, WscLen, pAuthorizedMACs, &AuthorizedMACsLen); } } #endif /* WSC_V2_SUPPORT */ break; default: DBGPRINT(RT_DEBUG_TRACE, ("WscSelectedRegistrar --> Unknown IE 0x%04x\n", WscType)); break; } /* Offset to net WSC Ie */ pData += WscLen; Length -= WscLen; } IsAPConfigured = pWscCtrl->WscConfStatus; if (wsc_sel_reg == 0x01) { pWscCtrl->WscSelReg = 1; WscBuildBeaconIE(pAd, WSC_SCSTATE_CONFIGURED, TRUE, wsc_dev_pass_id, wsc_sel_reg_conf_mthd, apidx, pAuthorizedMACs, AuthorizedMACsLen, AP_MODE); WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, TRUE, wsc_dev_pass_id, wsc_sel_reg_conf_mthd, pWscCtrl->EntryIfIdx, pAuthorizedMACs, AuthorizedMACsLen, AP_MODE); #ifdef WSC_V2_SUPPORT hex_dump("WscSelectedRegistrar - AuthorizedMACs::", pAuthorizedMACs, AuthorizedMACsLen); if ((AuthorizedMACsLen == 6) && (NdisEqualMemory(pAuthorizedMACs, BROADCAST_ADDR, MAC_ADDR_LEN) == FALSE) && (NdisEqualMemory(pAuthorizedMACs, ZERO_MAC_ADDR, MAC_ADDR_LEN) == FALSE) && (pWscCtrl->WscState <= WSC_STATE_WAIT_M3)) { PWSC_PEER_ENTRY pWscPeer = NULL; NdisMoveMemory(pWscCtrl->EntryAddr, pAuthorizedMACs, MAC_ADDR_LEN); RTMP_SEM_LOCK(&pWscCtrl->WscPeerListSemLock); WscClearPeerList(&pWscCtrl->WscPeerList); os_alloc_mem(pAd, (UCHAR **)&pWscPeer, sizeof(WSC_PEER_ENTRY)); if (pWscPeer) { NdisZeroMemory(pWscPeer, sizeof(WSC_PEER_ENTRY)); NdisMoveMemory(pWscPeer->mac_addr, pAuthorizedMACs, MAC_ADDR_LEN); NdisGetSystemUpTime(&pWscPeer->receive_time); insertTailList(&pWscCtrl->WscPeerList, (PLIST_ENTRY)pWscPeer); DBGPRINT(RT_DEBUG_TRACE, ("WscSelectedRegistrar --> Add this MAC to WscPeerList\n")); } ASSERT(pWscPeer != NULL); RTMP_SEM_UNLOCK(&pWscCtrl->WscPeerListSemLock); } #endif /* WSC_V2_SUPPORT */ } else { pWscCtrl->WscSelReg = 0; WscBuildBeaconIE(pAd, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, apidx, NULL, 0, AP_MODE); WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, pWscCtrl->EntryIfIdx, NULL, 0, AP_MODE); } APUpdateBeaconFrame(pAd, apidx); #ifdef WSC_V2_SUPPORT if (pAuthorizedMACs) os_free_mem(NULL, pAuthorizedMACs); #endif /* WSC_V2_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT /* ======================================================================== Routine Description: Make WSC IE for the ProbeReq frame Arguments: pAd - NIC Adapter pointer pOutBuf - all of WSC IE field pIeLen - length Return Value: None IRQL = DISPATCH_LEVEL Note: None ======================================================================== */ VOID WscBuildProbeReqIE( IN PRTMP_ADAPTER pAd, IN UCHAR CurOpMode, OUT PUCHAR pOutBuf, OUT PUCHAR pIeLen) { /* UCHAR WscIEFixed[] = {0xdd, 0x0e, 0x00, 0x50, 0xf2, 0x04}; // length will modify later */ WSC_IE_HEADER ieHdr; /* UCHAR OutMsgBuf[512]; // buffer to create message contents */ UCHAR *OutMsgBuf = NULL; /* buffer to create message contents */ INT Len =0, templen = 0; PUCHAR pData; USHORT tempVal = 0; PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pAd->StaCfg.WscControl.RegData; DBGPRINT(RT_DEBUG_INFO, ("-----> WscBuildProbeReqIE\n")); /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&OutMsgBuf, 512); if (OutMsgBuf == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } /* WSC IE Header */ ieHdr.elemId = 221; ieHdr.length = 4; ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50; ieHdr.oui[2] = 0xF2; #ifdef IWSC_SUPPORT if ((CurOpMode == STA_MODE) && (pAd->StaCfg.BssType == BSS_ADHOC)) ieHdr.oui[3] = 0x10; else #endif // IWSC_SUPPORT // ieHdr.oui[3] = 0x04; pData = (PUCHAR) &OutMsgBuf[0]; Len = 0; /* 1. Version */ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0); pData += templen; Len += templen; /* 2. Request Type */ if (pAd->StaCfg.WscControl.WscConfMode == WSC_REGISTRAR) tempVal = WSC_MSGTYPE_REGISTRAR; else if (pAd->StaCfg.WscControl.WscConfMode == WSC_ENROLLEE) tempVal = WSC_MSGTYPE_ENROLLEE_OPEN_8021X; else tempVal = WSC_MSGTYPE_ENROLLEE_INFO_ONLY; templen = AppendWSCTLV(WSC_ID_REQ_TYPE, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; /* 3. Config method */ #ifdef WSC_V2_SUPPORT if (pAd->StaCfg.WscControl.WscV2Info.bEnableWpsV2) { tempVal = pAd->StaCfg.WscControl.WscConfigMethods; } else #endif /* WSC_V2_SUPPORT */ { tempVal = (pAd->StaCfg.WscControl.WscConfigMethods & 0x00FF); } #ifdef IWSC_SUPPORT if ((CurOpMode == STA_MODE) && (pAd->StaCfg.BssType == BSS_ADHOC)) { if (pAd->StaCfg.IWscInfo.bLimitedUI) { tempVal &= (~WSC_CONFMET_KEYPAD); } else { tempVal |= WSC_CONFMET_KEYPAD; } } #endif /* IWSC_SUPPORT */ tempVal = cpu2be16(tempVal); templen = AppendWSCTLV(WSC_ID_CONFIG_METHODS, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; /* 4. UUID */ templen = AppendWSCTLV(WSC_ID_UUID_E, pData, pReg->SelfInfo.Uuid, 0); pData += templen; Len += templen; /* 5. Primary device type */ templen = AppendWSCTLV(WSC_ID_PRIM_DEV_TYPE, pData, pReg->SelfInfo.PriDeviceType, 0); pData += templen; Len += templen; /* 6. RF band, shall change based on current channel */ templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, &pReg->SelfInfo.RfBand, 0); pData += templen; Len += templen; /* 7. Associate state */ tempVal = pReg->SelfInfo.AssocState; templen = AppendWSCTLV(WSC_ID_ASSOC_STATE, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; /* 8. Config error */ tempVal = pReg->SelfInfo.ConfigError; templen = AppendWSCTLV(WSC_ID_CONFIG_ERROR, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; /* 9. Device password ID */ tempVal = pReg->SelfInfo.DevPwdId; templen = AppendWSCTLV(WSC_ID_DEVICE_PWD_ID, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; #ifdef IWSC_SUPPORT if ((pAd->StaCfg.BssType == BSS_ADHOC) && (CurOpMode == STA_MODE)) { /* Connection Type Flag ESS */ templen = AppendWSCTLV(WSC_ID_CONN_TYPE, pData, (UINT8 *)&pReg->SelfInfo.ConnTypeFlags, 0); pData += templen; Len += templen; /* Connection Type Flag ESS */ tempVal = htons(pAd->StaCfg.IWscInfo.IpMethod); templen = AppendWSCTLV(WSC_ID_IP_ADDR_CONF_METHOD, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; } #endif /* IWSC_SUPPORT */ #ifdef WSC_V2_SUPPORT if (pAd->StaCfg.WscControl.WscV2Info.bEnableWpsV2) { /* 10. Manufacturer */ NdisZeroMemory(pData, 64 + 4); templen = AppendWSCTLV(WSC_ID_MANUFACTURER, pData, pReg->SelfInfo.Manufacturer, strlen((PSTRING) pReg->SelfInfo.Manufacturer)); pData += templen; Len += templen; /* 11. Model Name */ NdisZeroMemory(pData, 32 + 4); templen = AppendWSCTLV(WSC_ID_MODEL_NAME, pData, pReg->SelfInfo.ModelName, strlen((PSTRING) pReg->SelfInfo.ModelName)); pData += templen; Len += templen; /* 12. Model Number */ NdisZeroMemory(pData, 32 + 4); templen = AppendWSCTLV(WSC_ID_MODEL_NUMBER, pData, pReg->SelfInfo.ModelNumber, strlen((PSTRING) pReg->SelfInfo.ModelNumber)); pData += templen; Len += templen; /* 13. Device Name */ NdisZeroMemory(pData, 32 + 4); templen = AppendWSCTLV(WSC_ID_DEVICE_NAME, pData, pReg->SelfInfo.DeviceName, strlen((PSTRING) pReg->SelfInfo.DeviceName)); pData += templen; Len += templen; /* Version2 */ WscGenV2Msg(&pAd->StaCfg.WscControl, FALSE, NULL, 0, &pData, &Len); } #endif /* WSC_V2_SUPPORT */ ieHdr.length = ieHdr.length + Len; RTMPMoveMemory(pOutBuf, &ieHdr, sizeof(WSC_IE_HEADER)); RTMPMoveMemory(pOutBuf + sizeof(WSC_IE_HEADER), OutMsgBuf, Len); *pIeLen = sizeof(WSC_IE_HEADER) + Len; if (OutMsgBuf != NULL) os_free_mem(NULL, OutMsgBuf); DBGPRINT(RT_DEBUG_INFO, ("<----- WscBuildProbeReqIE\n")); } /* ======================================================================== Routine Description: Make WSC IE for the AssocReq frame Arguments: pAd - NIC Adapter pointer pOutBuf - all of WSC IE field pIeLen - length Return Value: None IRQL = DISPATCH_LEVEL Note: None ======================================================================== */ VOID WscBuildAssocReqIE( /*IN PRTMP_ADAPTER pAd,*/ IN PWSC_CTRL pWscControl, OUT PUCHAR pOutBuf, OUT PUCHAR pIeLen) { WSC_IE_HEADER ieHdr; /* UCHAR Data[512]; */ UCHAR *Data = NULL; PUCHAR pData; INT Len = 0, templen = 0; UINT8 tempVal = 0; PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscControl->RegData; if (pWscControl == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("WscBuildAssocReqIE: pWscControl is NULL\n")); return; } DBGPRINT(RT_DEBUG_TRACE, ("-----> WscBuildAssocReqIE\n")); /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&Data, 512); if (Data == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } /* WSC IE Header */ ieHdr.elemId = 221; ieHdr.length = 4; ieHdr.oui[0] = 0x00; ieHdr.oui[1] = 0x50; ieHdr.oui[2] = 0xF2; ieHdr.oui[3] = 0x04; pData = (PUCHAR) &Data[0]; Len = 0; /* Version */ templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0); pData += templen; Len += templen; /* Request Type */ if (pWscControl->WscConfMode == WSC_ENROLLEE) tempVal = WSC_MSGTYPE_ENROLLEE_INFO_ONLY; else tempVal = WSC_MSGTYPE_REGISTRAR; templen = AppendWSCTLV(WSC_ID_REQ_TYPE, pData, (UINT8 *)&tempVal, 0); pData += templen; Len += templen; #ifdef WSC_V2_SUPPORT if (pWscControl->WscV2Info.bEnableWpsV2) { /* Version2 */ WscGenV2Msg(pWscControl, FALSE, NULL, 0, &pData, &Len); } #endif /* WSC_V2_SUPPORT */ 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, ("<----- WscBuildAssocReqIE\n")); } #endif /* CONFIG_STA_SUPPORT */ VOID WscProfileRetryTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAdapter = NULL; PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext; BOOLEAN bReConnect = TRUE; UCHAR CurOpMode = 0xFF; if (pWscControl == NULL) return; pAdapter = pWscControl->pAd; if (pAdapter != NULL) { DBGPRINT(RT_DEBUG_TRACE, ("WscProfileRetryTimeout:: WSC profile retry timeout index: %d\n", pWscControl->WscProfile.ApplyProfileIdx)); #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAdapter) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter) CurOpMode = AP_MODE; #ifdef APCLI_SUPPORT if( (CurOpMode == AP_MODE) && (pAdapter->ApCfg.ApCliTab[BSS0].CtrlCurrState == APCLI_CTRL_CONNECTED) && (pAdapter->ApCfg.ApCliTab[BSS0].SsidLen != 0)) { INT i; for (i=0; iMacTab.Content[i]; if ( IS_ENTRY_APCLI(pEntry) && (pEntry->Sst == SST_ASSOC) && (pEntry->PortSecured == WPA_802_1X_PORT_SECURED)) { bReConnect = FALSE; } } } #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ if ((CurOpMode == STA_MODE) && INFRA_ON(pAdapter) && (pAdapter->IndicateMediaState == NdisMediaStateConnected)) { pWscControl->WscProfileRetryTimerRunning = FALSE; bReConnect = FALSE; } if (bReConnect) { if (pWscControl->WscProfile.ApplyProfileIdx < pWscControl->WscProfile.ProfileCnt-1) pWscControl->WscProfile.ApplyProfileIdx++; else pWscControl->WscProfile.ApplyProfileIdx = 0; #ifdef APCLI_SUPPORT if (CurOpMode == AP_MODE) { BOOLEAN apcliEn; WscWriteConfToApCliCfg(pAdapter, pWscControl, &pWscControl->WscProfile.Profile[pWscControl->WscProfile.ApplyProfileIdx], TRUE); apcliEn = pAdapter->ApCfg.ApCliTab[BSS0].Enable; /* bring apcli interface down first */ if(apcliEn == TRUE ) { pAdapter->ApCfg.ApCliTab[BSS0].Enable = FALSE; ApCliIfDown(pAdapter); pAdapter->ApCfg.ApCliTab[BSS0].Enable = TRUE; } } #endif /* APCLI_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { WscWriteConfToPortCfg(pAdapter, pWscControl, &pWscControl->WscProfile.Profile[pWscControl->WscProfile.ApplyProfileIdx], TRUE); } #endif /* CONFIG_STA_SUPPORT */ pAdapter->WriteWscCfgToDatFile = (pWscControl->EntryIfIdx & 0x0F); /*#ifdef KTHREAD_SUPPORT */ /* WAKE_UP(&(pAdapter->wscTask)); */ /*#else */ /* RTMP_SEM_EVENT_UP(&(pAdapter->wscTask.taskSema)); */ /*#endif */ RtmpOsTaskWakeUp(&(pAdapter->wscTask)); DBGPRINT(RT_DEBUG_TRACE, ("WscProfileRetryTimeout:: WSC profile retry index: %d\n", pWscControl->WscProfile.ApplyProfileIdx)); } #ifdef CONFIG_STA_SUPPORT pAdapter->StaCfg.bAutoConnectByBssid = FALSE; #endif /* CONFIG_STA_SUPPORT */ } } VOID WscPBCTimeOutAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext; RTMP_ADAPTER *pAd = NULL; BOOLEAN Cancelled; DBGPRINT(RT_DEBUG_OFF, ("-----> WscPBCTimeOutAction\n")); if (pWscControl != NULL) pAd = pWscControl->pAd; if (pAd != NULL) { if (pWscControl->WscPBCTimerRunning) { pWscControl->WscPBCTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscPBCTimer, &Cancelled); } WscPBCExec(pAd, FALSE, pWscControl); /* call Mlme handler to execute it */ RTMP_MLME_HANDLER(pAd); } DBGPRINT(RT_DEBUG_OFF, ("<----- WscPBCTimeOutAction\n")); } /* ======================================================================== Routine Description: Exec scan after scan timer expiration Arguments: FunctionContext NIC Adapter pointer Return Value: None IRQL = DISPATCH_LEVEL Note: ======================================================================== */ VOID WscScanTimeOutAction( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { RTMP_ADAPTER *pAd = NULL; PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext; if (pWscControl == NULL) return; pAd = pWscControl->pAd; if (pAd != NULL) { /* call to execute the scan actions */ WscScanExec(pAd, pWscControl); /* register 10 second timer for PBC or PIN connection execution */ if (pWscControl->WscMode == WSC_PBC_MODE) { /* Prevent infinite loop if conncet time out didn't stop the repeat scan */ if (pWscControl->WscState != WSC_STATE_OFF) { RTMPSetTimer(&pWscControl->WscPBCTimer, 10000); pWscControl->WscPBCTimerRunning = TRUE; } } else if (pWscControl->WscMode == WSC_PIN_MODE) { /* Prevent infinite loop if conncet time out didn't stop the repeat scan */ } DBGPRINT(RT_DEBUG_OFF, ("!!! WscScanTimeOutAction !!!\n")); /* call Mlme handler to execute it */ RTMP_MLME_HANDLER(pAd); } } BOOLEAN ValidateChecksum( IN UINT PIN) { UINT accum = 0; accum += 3 * ((PIN / 10000000) % 10); accum += 1 * ((PIN / 1000000) % 10); accum += 3 * ((PIN / 100000) % 10); accum += 1 * ((PIN / 10000) % 10); accum += 3 * ((PIN / 1000) % 10); accum += 1 * ((PIN / 100) % 10); accum += 3 * ((PIN / 10) % 10); accum += 1 * ((PIN / 1) % 10); return (0 == (accum % 10)); } /* ValidateChecksum */ /* Generate 4-digit random number, ex:1234 */ UINT WscRandomGen4digitPinCode( IN PRTMP_ADAPTER pAd) { UINT iPin; iPin = RandomByte2(pAd) * 256 * 256 + RandomByte2(pAd) * 256 + RandomByte2(pAd); iPin = iPin % 10000; return iPin; } UINT WscRandomGeneratePinCode( IN PRTMP_ADAPTER pAd, IN UCHAR apidx) { UINT iPin; UINT checksum; iPin = RandomByte(pAd) * 256 * 256 + RandomByte(pAd) * 256 + RandomByte(pAd); iPin = iPin % 10000000; checksum = ComputeChecksum( iPin ); iPin = iPin*10 + checksum; return iPin; } #ifdef CONFIG_AP_SUPPORT VOID WscInformFromWPA( IN PMAC_TABLE_ENTRY pEntry) { /* WPA_STATE_MACHINE informs this Entry is already WPA_802_1X_PORT_SECURED. */ RTMP_ADAPTER *pAd = (PRTMP_ADAPTER)pEntry->pAd; BOOLEAN Cancelled; if (pEntry->apidx >= pAd->ApCfg.BssidNum) return; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscInformFromWPA\n")); if (MAC_ADDR_EQUAL(pEntry->Addr, pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr)) { NdisZeroMemory(pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EntryAddr, MAC_ADDR_LEN); RTMPCancelTimer(&pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EapolTimer, &Cancelled); pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.EapolTimerRunning = FALSE; pEntry->bWscCapable = FALSE; pAd->ApCfg.MBSSID[pEntry->apidx].WscControl.WscState = WSC_STATE_CONFIGURED; DBGPRINT(RT_DEBUG_TRACE, ("Reset EntryIfIdx to %d\n", WSC_INIT_ENTRY_APIDX)); } DBGPRINT(RT_DEBUG_TRACE, ("<----- WscInformFromWPA\n")); } VOID WscDelWPARetryTimer( IN PRTMP_ADAPTER pAd) { PMAC_TABLE_ENTRY pEntry; UCHAR apidx = MAIN_MBSSID; BOOLEAN Cancelled; DBGPRINT(RT_DEBUG_TRACE, ("<----- WscDelWPARetryTimer\n")); pEntry = MacTableLookup(pAd, pAd->ApCfg.MBSSID[apidx].WscControl.EntryAddr); if (pEntry) { RTMPCancelTimer(&pEntry->RetryTimer, &Cancelled); pEntry->WpaState = AS_NOTUSE; } DBGPRINT(RT_DEBUG_TRACE, ("<----- WscDelWPARetryTimer\n")); } #endif /* CONFIG_AP_SUPPORT */ VOID WscStop( IN PRTMP_ADAPTER pAd, #ifdef CONFIG_AP_SUPPORT IN BOOLEAN bFromApCli, #endif /* CONFIG_AP_SUPPORT */ IN PWSC_CTRL pWscControl) { PWSC_UPNP_NODE_INFO pWscUPnPInfo; BOOLEAN Cancelled; #ifdef WSC_LED_SUPPORT UCHAR WPSLEDStatus; #endif /* WSC_LED_SUPPORT */ #ifdef CONFIG_AP_SUPPORT MAC_TABLE_ENTRY *pEntry; UCHAR apidx = (pWscControl->EntryIfIdx & 0x0F); #endif /* CONFIG_AP_SUPPORT */ UCHAR CurOpMode = 0xff; #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) CurOpMode = AP_MODE; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) CurOpMode = STA_MODE; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx != BSS0) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) pWscControl->bConfiguredAP = FALSE; #endif /* CONFIG_STA_SUPPORT */ pWscUPnPInfo = &pWscControl->WscUPnPNodeInfo; if(pWscUPnPInfo->bUPnPMsgTimerRunning == TRUE) { pWscUPnPInfo->bUPnPMsgTimerRunning = FALSE; RTMPCancelTimer(&pWscUPnPInfo->UPnPMsgTimer, &Cancelled); pWscUPnPInfo->bUPnPMsgTimerPending = FALSE; } if(pWscControl->bM2DTimerRunning) { pWscControl->bM2DTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->M2DTimer, &Cancelled); } pWscUPnPInfo->bUPnPInProgress = FALSE; pWscControl->M2DACKBalance = 0; pWscUPnPInfo->registrarID = 0; if (pWscControl->Wsc2MinsTimerRunning) { pWscControl->Wsc2MinsTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled); } if (pWscControl->WscUpdatePortCfgTimerRunning) { pWscControl->WscUpdatePortCfgTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscUpdatePortCfgTimer, &Cancelled); } RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); pWscControl->EapolTimerRunning = FALSE; #ifdef CONFIG_AP_SUPPORT #ifdef WSC_V2_SUPPORT if (pWscControl->WscSetupLockTimerRunning) { pWscControl->WscSetupLockTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscSetupLockTimer, &Cancelled); } #endif /* WSC_V2_SUPPORT */ if ((pWscControl->EntryIfIdx & 0x0F)< pAd->ApCfg.BssidNum) { pEntry = MacTableLookup(pAd, pWscControl->EntryAddr); if (CurOpMode == AP_MODE) { if (pEntry && !bFromApCli) { pEntry->bWscCapable = FALSE; } } } #endif /* CONFIG_AP_SUPPORT */ NdisZeroMemory(pWscControl->EntryAddr, MAC_ADDR_LEN); pWscControl->WscSelReg = 0; if ( (pWscControl->WscStatus == STATUS_WSC_CONFIGURED) || (pWscControl->WscStatus == STATUS_WSC_FAIL) || (pWscControl->WscStatus == STATUS_WSC_PBC_TOO_MANY_AP)) ; else pWscControl->WscStatus = STATUS_WSC_NOTUSED; pWscControl->WscState = WSC_STATE_OFF; pWscControl->lastId = 1; pWscControl->EapMsgRunning = FALSE; pWscControl->EapolTimerPending = FALSE; pWscControl->bWscTrigger = FALSE; if (pWscControl->WscScanTimerRunning) { pWscControl->WscScanTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscScanTimer, &Cancelled); } if (pWscControl->WscPBCTimerRunning) { pWscControl->WscPBCTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscPBCTimer, &Cancelled); } #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pAd->MlmeAux.AutoReconnectSsidLen = pAd->MlmeAux.SsidLen; NdisZeroMemory(&pAd->MlmeAux.AutoReconnectSsid[0], MAX_LEN_OF_SSID); NdisMoveMemory(&pAd->MlmeAux.AutoReconnectSsid[0], &pAd->MlmeAux.Ssid[0], pAd->MlmeAux.SsidLen); } #endif /* CONFIG_STA_SUPPORT */ #ifdef WSC_LED_SUPPORT if (pWscControl->WscLEDTimerRunning) { pWscControl->WscLEDTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscLEDTimer, &Cancelled); } if (pWscControl->WscSkipTurnOffLEDTimerRunning) { pWscControl->WscSkipTurnOffLEDTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscSkipTurnOffLEDTimer, &Cancelled); } /* Reset the WPS walk time. */ pWscControl->bWPSWalkTimeExpiration = FALSE; WPSLEDStatus = LED_WPS_TURN_LED_OFF; RTMPSetLED(pAd, WPSLEDStatus); #endif /* WSC_LED_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { #ifdef APCLI_SUPPORT if (!bFromApCli) #endif /* APCLI_SUPPORT */ { pAd->ApCfg.MBSSID[apidx].WscIEBeacon.ValueLen = 0; pAd->ApCfg.MBSSID[apidx].WscIEProbeResp.ValueLen = 0; } } #endif /* CONFIG_AP_SUPPORT */ } VOID WscInit( IN PRTMP_ADAPTER pAd, IN BOOLEAN bFromApCli, IN UCHAR BssIndex) { IN PWSC_CTRL pWscControl = NULL; #ifdef CONFIG_STA_SUPPORT #endif /* CONFIG_STA_SUPPORT */ UCHAR CurOpMode = AP_MODE; #ifdef CONFIG_AP_SUPPORT INT IsAPConfigured; IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { #ifdef APCLI_SUPPORT if (bFromApCli) pWscControl = &pAd->ApCfg.ApCliTab[BssIndex & 0x0F].WscControl; else #endif /* APCLI_SUPPORT */ pWscControl = &pAd->ApCfg.MBSSID[BssIndex & 0x0F].WscControl; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { #ifdef P2P_SUPPORT if (BssIndex >= MIN_NET_DEVICE_FOR_P2P_GO) { pWscControl = &pAd->ApCfg.MBSSID[MAIN_MBSSID].WscControl; } else if (bFromApCli) { pWscControl = &pAd->ApCfg.ApCliTab[MAIN_MBSSID].WscControl; } else #endif /* P2P_SUPPORT */ { pWscControl = &pAd->StaCfg.WscControl; CurOpMode = STA_MODE; } } #endif /* CONFIG_STA_SUPPORT */ if (pWscControl == NULL) return; if (pWscControl->WscEnrolleePinCode == 0) { if (pWscControl->WscEnrollee4digitPinCode) { pWscControl->WscEnrolleePinCodeLen = 4; pWscControl->WscEnrolleePinCode = WscRandomGen4digitPinCode(pAd); } else { pWscControl->WscEnrolleePinCode = GenerateWpsPinCode(pAd, bFromApCli, BssIndex); pWscControl->WscEnrolleePinCodeLen = 8; } } pWscControl->RegData.SelfInfo.Version = WSC_VERSION; #ifdef WSC_V2_SUPPORT pWscControl->RegData.SelfInfo.Version2 = WSC_V2_VERSION; #endif /* WSC_V2_SUPPORT */ pWscControl->bWscLastOne = FALSE; pWscControl->bWscFirstOne = FALSE; #ifdef CONFIG_STA_SUPPORT #endif /* CONFIG_STA_SUPPORT */ pWscControl->WscStatus = STATUS_WSC_IDLE; #ifdef CONFIG_AP_SUPPORT if (((CurOpMode == AP_MODE) && (pWscControl->WscConfMode == WSC_DISABLE)) #ifdef WSC_V2_SUPPORT || ((pWscControl->WscV2Info.bWpsEnable == FALSE) && pWscControl->WscV2Info.bEnableWpsV2) #endif /* WSC_V2_SUPPORT */ ) { if (CurOpMode == AP_MODE) { #ifdef APCLI_SUPPORT if (!bFromApCli) #endif /* APCLI_SUPPORT */ { pAd->ApCfg.MBSSID[BssIndex & 0x0F].WscIEBeacon.ValueLen = 0; pAd->ApCfg.MBSSID[BssIndex & 0x0F].WscIEProbeResp.ValueLen = 0; } } } else #endif /* CONFIG_AP_SUPPORT */ { #ifdef P2P_SUPPORT if (pWscControl->WscConfMode == WSC_DISABLE) { if (BssIndex >= MIN_NET_DEVICE_FOR_P2P_GO) { pAd->ApCfg.MBSSID[MAIN_MBSSID].WscIEBeacon.ValueLen = 0; pAd->ApCfg.MBSSID[MAIN_MBSSID].WscIEProbeResp.ValueLen = 0; } return; } #endif /* P2P_SUPPORT */ WscInitRegistrarPair(pAd, pWscControl, BssIndex); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { #ifdef APCLI_SUPPORT if (!bFromApCli) #endif /* APCLI_SUPPORT */ { IsAPConfigured = pWscControl->WscConfStatus; WscBuildBeaconIE(pAd, IsAPConfigured, FALSE, 0, 0, (BssIndex & 0x0F), NULL, 0, AP_MODE); WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, FALSE, 0, 0, BssIndex, NULL, 0, AP_MODE); APUpdateBeaconFrame(pAd, pWscControl->EntryIfIdx & 0x0F); } } #endif /* CONFIG_AP_SUPPORT */ } } USHORT WscGetAuthType( IN NDIS_802_11_AUTHENTICATION_MODE authType) { switch(authType) { case Ndis802_11AuthModeOpen: return WSC_AUTHTYPE_OPEN; case Ndis802_11AuthModeWPAPSK: return WSC_AUTHTYPE_WPAPSK; case Ndis802_11AuthModeShared: return WSC_AUTHTYPE_SHARED; case Ndis802_11AuthModeWPANone: return WSC_AUTHTYPE_WPANONE; case Ndis802_11AuthModeWPA: return WSC_AUTHTYPE_WPA; case Ndis802_11AuthModeWPA1WPA2: return (WSC_AUTHTYPE_WPA | WSC_AUTHTYPE_WPA2); case Ndis802_11AuthModeWPA2: return WSC_AUTHTYPE_WPA2; case Ndis802_11AuthModeWPA1PSKWPA2PSK: return (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK); case Ndis802_11AuthModeWPA2PSK: return WSC_AUTHTYPE_WPA2PSK; default: return WSC_AUTHTYPE_OPEN; } } USHORT WscGetEncryType( IN NDIS_802_11_WEP_STATUS encryType) { switch(encryType) { case Ndis802_11WEPDisabled: return WSC_ENCRTYPE_NONE; case Ndis802_11WEPEnabled: return WSC_ENCRTYPE_WEP; case Ndis802_11Encryption2Enabled: return WSC_ENCRTYPE_TKIP; case Ndis802_11Encryption4Enabled: return (WSC_ENCRTYPE_AES | WSC_ENCRTYPE_TKIP); default: case Ndis802_11Encryption3Enabled: return WSC_ENCRTYPE_AES; } } PSTRING WscGetAuthTypeStr( IN USHORT authFlag) { switch(authFlag) { case WSC_AUTHTYPE_OPEN: return "OPEN"; case WSC_AUTHTYPE_WPAPSK: return "WPAPSK"; case WSC_AUTHTYPE_SHARED: return "SHARED"; case WSC_AUTHTYPE_WPANONE: return "WPANONE"; case WSC_AUTHTYPE_WPA: return "WPA"; case WSC_AUTHTYPE_WPA2: return "WPA2"; default: case (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK): return "WPAPSKWPA2PSK"; case WSC_AUTHTYPE_WPA2PSK: return "WPA2PSK"; case (WSC_AUTHTYPE_OPEN | WSC_AUTHTYPE_SHARED): return "WEPAUTO"; } } PSTRING WscGetEncryTypeStr( IN USHORT encryFlag) { switch(encryFlag) { case WSC_ENCRTYPE_NONE: return "NONE"; case WSC_ENCRTYPE_WEP: return "WEP"; case WSC_ENCRTYPE_TKIP: return "TKIP"; default: case (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES): return "TKIPAES"; case WSC_ENCRTYPE_AES: return "AES"; } } NDIS_802_11_AUTHENTICATION_MODE WscGetAuthMode( IN USHORT authFlag) { switch(authFlag) { case WSC_AUTHTYPE_OPEN: return Ndis802_11AuthModeOpen; case WSC_AUTHTYPE_WPAPSK: return Ndis802_11AuthModeWPAPSK; case WSC_AUTHTYPE_SHARED: return Ndis802_11AuthModeShared; case WSC_AUTHTYPE_WPANONE: return Ndis802_11AuthModeWPANone; case WSC_AUTHTYPE_WPA: return Ndis802_11AuthModeWPA; case WSC_AUTHTYPE_WPA2: return Ndis802_11AuthModeWPA2; default: case (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK): return Ndis802_11AuthModeWPA1PSKWPA2PSK; case WSC_AUTHTYPE_WPA2PSK: return Ndis802_11AuthModeWPA2PSK; } } NDIS_802_11_WEP_STATUS WscGetWepStatus( IN USHORT encryFlag) { switch(encryFlag) { case WSC_ENCRTYPE_NONE: return Ndis802_11WEPDisabled; case WSC_ENCRTYPE_WEP: return Ndis802_11WEPEnabled; case WSC_ENCRTYPE_TKIP: return Ndis802_11Encryption2Enabled; default: case (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES): return Ndis802_11Encryption4Enabled; case WSC_ENCRTYPE_AES: return Ndis802_11Encryption3Enabled; } } void WscWriteConfToPortCfg( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl, IN PWSC_CREDENTIAL pCredential, IN BOOLEAN bEnrollee) { UCHAR CurApIdx = MAIN_MBSSID; UCHAR CurOpMode = AP_MODE; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscWriteConfToPortCfg\n")); #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (pWscControl->EntryIfIdx == BSS0) CurOpMode = STA_MODE; } #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { CurApIdx = (pWscControl->EntryIfIdx & 0x0F); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_AP_SUPPORT if (bEnrollee || (CurOpMode == AP_MODE)) { if (CurOpMode == AP_MODE) { NdisZeroMemory(pAd->ApCfg.MBSSID[CurApIdx].Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(pAd->ApCfg.MBSSID[CurApIdx].Ssid, pCredential->SSID.Ssid, pCredential->SSID.SsidLength); pAd->ApCfg.MBSSID[CurApIdx].SsidLen = pCredential->SSID.SsidLength; #ifdef P2P_SUPPORT if (P2P_GO_ON(pAd)) { NdisZeroMemory(pAd->P2pCfg.SSID, MAX_LEN_OF_SSID); pAd->P2pCfg.SSIDLen = pCredential->SSID.SsidLength; NdisMoveMemory(pAd->P2pCfg.SSID, pCredential->SSID.Ssid, pAd->P2pCfg.SSIDLen); } #endif /* P2P_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pAd->MlmeAux.AutoReconnectSsidLen = pCredential->SSID.SsidLength; NdisZeroMemory(pAd->MlmeAux.AutoReconnectSsid, NDIS_802_11_LENGTH_SSID); NdisMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pCredential->SSID.Ssid, pAd->MlmeAux.AutoReconnectSsidLen); pAd->MlmeAux.SsidLen = pCredential->SSID.SsidLength; NdisZeroMemory(pAd->MlmeAux.Ssid, NDIS_802_11_LENGTH_SSID); NdisMoveMemory(pAd->MlmeAux.Ssid, pCredential->SSID.Ssid, pAd->MlmeAux.SsidLen); if (!NdisEqualMemory(pCredential->MacAddr, pAd->CurrentAddress, MAC_ADDR_LEN)) { NdisZeroMemory(pAd->MlmeAux.Bssid, MAC_ADDR_LEN); NdisMoveMemory(pAd->MlmeAux.Bssid, pCredential->MacAddr, MAC_ADDR_LEN); } } #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("ra%d - AuthType: %u, EncrType: %u\n", CurApIdx, pCredential->AuthType, pCredential->EncrType)); if (pCredential->AuthType & (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK | WSC_AUTHTYPE_WPANONE)) { if (!(pCredential->EncrType & (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES))) { DBGPRINT(RT_DEBUG_TRACE, ("AuthType is WPAPSK or WPA2PAK.\n" "Get illegal EncrType(%d) from External Registrar, set EncrType to TKIP\n", pCredential->EncrType)); pCredential->EncrType = WSC_ENCRTYPE_TKIP; } #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) pAd->StaCfg.WpaState = SS_START; #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_AP_SUPPORT #ifdef WSC_V2_SUPPORT if ((CurOpMode == AP_MODE) && (pWscControl->WscV2Info.bEnableWpsV2)) { if (pCredential->AuthType == WSC_AUTHTYPE_WPAPSK) pCredential->AuthType = (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK); if (pCredential->EncrType == WSC_ENCRTYPE_TKIP) pCredential->EncrType = (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES); } #endif /* WSC_V2_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ } WscSetAuthMode(pAd, CurOpMode, CurApIdx, WscGetAuthTypeStr(pCredential->AuthType)); WscSetEncrypType(pAd, CurOpMode, CurApIdx, WscGetEncryTypeStr(pCredential->EncrType)); if (pCredential->EncrType != WSC_ENCRTYPE_NONE) { if (pCredential->EncrType & (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES)) { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) pAd->ApCfg.MBSSID[CurApIdx].DefaultKeyId = 1; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) pAd->StaCfg.DefaultKeyId = 0; #endif /* CONFIG_STA_SUPPORT */ if (pCredential->KeyLength >= 8 && pCredential->KeyLength <= 64) { UCHAR *pPMKBuf = NULL, *pSSIDStr = NULL; INT ssidLen = 0; pWscControl->WpaPskLen = pCredential->KeyLength; RTMPZeroMemory(pWscControl->WpaPsk, 64); RTMPMoveMemory(pWscControl->WpaPsk, pCredential->Key, pWscControl->WpaPskLen); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { pPMKBuf = pAd->ApCfg.MBSSID[CurApIdx].PMK; pSSIDStr = (PUCHAR)pAd->ApCfg.MBSSID[CurApIdx].Ssid; ssidLen = pAd->ApCfg.MBSSID[CurApIdx].SsidLen; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { RTMPZeroMemory(pAd->StaCfg.WpaPassPhrase, 64); RTMPMoveMemory(pAd->StaCfg.WpaPassPhrase, pCredential->Key, pWscControl->WpaPskLen); pAd->StaCfg.WpaPassPhraseLen = pCredential->KeyLength; pPMKBuf = pAd->StaCfg.PMK; pSSIDStr = (PUCHAR)pCredential->SSID.Ssid; ssidLen = pCredential->SSID.SsidLength; } #endif /* CONFIG_STA_SUPPORT */ RT_CfgSetWPAPSKKey(pAd, pCredential->Key, pWscControl->WpaPskLen, pSSIDStr, ssidLen, pPMKBuf); DBGPRINT(RT_DEBUG_TRACE, ("WpaPskLen = %d\n", pWscControl->WpaPskLen)); } else { pWscControl->WpaPskLen = 0; DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK: Invalid Key Length (%d)\n", pCredential->KeyLength)); } } else if (pCredential->EncrType == WSC_ENCRTYPE_WEP) { UCHAR WepKeyId = 0; USHORT WepKeyLen = pCredential->KeyLength; if ((pCredential->KeyIndex >= 1) && (pCredential->KeyIndex <= 4)) { WepKeyId = (pCredential->KeyIndex - 1); /* KeyIndex = 1 ~ 4 */ #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) pAd->ApCfg.MBSSID[CurApIdx].DefaultKeyId = WepKeyId; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) pAd->StaCfg.DefaultKeyId = WepKeyId; #endif /* CONFIG_STA_SUPPORT */ /* 5 or 13 ASCII characters */ /* 10 or 26 Hex characters */ if (WepKeyLen == 5 || WepKeyLen == 13 || WepKeyLen == 10 || WepKeyLen == 26) { if (WepKeyLen == 5 || WepKeyLen == 13) { pAd->SharedKey[CurApIdx][WepKeyId].KeyLen = (UCHAR)WepKeyLen; memcpy(pAd->SharedKey[CurApIdx][WepKeyId].Key, pCredential->Key, WepKeyLen); if (WepKeyLen == 5) pAd->SharedKey[CurApIdx][WepKeyId].CipherAlg = CIPHER_WEP64; else pAd->SharedKey[CurApIdx][WepKeyId].CipherAlg = CIPHER_WEP128; } else { pAd->SharedKey[CurApIdx][WepKeyId].KeyLen = (UCHAR)(WepKeyLen/2); AtoH((PSTRING) pCredential->Key, pAd->SharedKey[CurApIdx][WepKeyId].Key, WepKeyLen/2); if (WepKeyLen == 10) pAd->SharedKey[CurApIdx][WepKeyId].CipherAlg = CIPHER_WEP64; else pAd->SharedKey[CurApIdx][WepKeyId].CipherAlg = CIPHER_WEP128; } } else DBGPRINT(RT_DEBUG_TRACE, ("WEP: Invalid Key Length (%d)\n", pCredential->KeyLength)); } else { DBGPRINT(RT_DEBUG_TRACE, ("Unsupport default key index (%d)\n", WepKeyId)); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) pAd->ApCfg.MBSSID[CurApIdx].DefaultKeyId = 0; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) pAd->StaCfg.DefaultKeyId = 0; #endif /* CONFIG_STA_SUPPORT */ } } } #ifdef CONFIG_AP_SUPPORT } else { if (CurOpMode == AP_MODE) { pAd->ApCfg.MBSSID[CurApIdx].DefaultKeyId = 1; WscSetAuthMode(pAd, CurOpMode, CurApIdx, "WPAPSKWPA2PSK"); WscSetEncrypType(pAd, CurOpMode, CurApIdx, "TKIPAES"); pWscControl->WpaPskLen = (INT)pCredential->KeyLength; NdisZeroMemory(pWscControl->WpaPsk, 64); NdisMoveMemory(pWscControl->WpaPsk, pCredential->Key, pWscControl->WpaPskLen); /* Copy SSID */ NdisZeroMemory(pAd->ApCfg.MBSSID[CurApIdx].Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(pAd->ApCfg.MBSSID[CurApIdx].Ssid, pCredential->SSID.Ssid, pCredential->SSID.SsidLength); pAd->ApCfg.MBSSID[CurApIdx].SsidLen = pCredential->SSID.SsidLength; /* Hex Key */ if(pWscControl->WscKeyASCII == 0) { AtoH((PSTRING) pWscControl->WpaPsk, pAd->ApCfg.MBSSID[CurApIdx].PMK, 32); } else { UCHAR keyMaterial[40] = {0}; RtmpPasswordHash((PSTRING)pWscControl->WpaPsk, (PUCHAR) pAd->ApCfg.MBSSID[CurApIdx].Ssid, pAd->ApCfg.MBSSID[CurApIdx].SsidLen, keyMaterial); NdisMoveMemory(pAd->ApCfg.MBSSID[CurApIdx].PMK, keyMaterial, 32); } } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { /* Atheros WPS Testbed AP will put A-Band BSSID in credential of M7. To prevent 2.4G only STA would fail to re-connect by BSSID, set profile retry timer here. */ if ((pAd->StaCfg.BssType == BSS_INFRA) && (pWscControl->WscDriverAutoConnect == 2) && (pWscControl->WscProfile.ProfileCnt >= 1)) { pWscControl->WscProfileRetryTimerRunning = TRUE; RTMPSetTimer(&pWscControl->WscProfileRetryTimer, WSC_PROFILE_RETRY_TIME_OUT); } #ifdef IWSC_SUPPORT if ((pAd->StaCfg.BssType == BSS_ADHOC) && (pAd->StaCfg.IWscInfo.RegDepth != 0) && (pAd->StaCfg.IWscInfo.AvaSubMaskListCount != 0)) { if ((pCredential->AvaIpv4SubmaskList[0] == 0) && (pCredential->AvaIpv4SubmaskList[1] == 0) && (pCredential->AvaIpv4SubmaskList[2] == 0)) pAd->StaCfg.IWscInfo.AvaSubMaskListCount = 0; } #endif /* IWSC_SUPPORT */ } #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("<----- ra%d - WscWriteConfToPortCfg\n", CurApIdx)); } VOID WscWriteSsidToDatFile( IN PRTMP_ADAPTER pAd, IN PSTRING pTempStr, IN BOOLEAN bNewFormat, IN UCHAR CurOpMode) { #ifdef CONFIG_AP_SUPPORT UCHAR apidx; #endif /* CONFIG_AP_SUPPORT */ INT offset = 0; if (bNewFormat == FALSE) { NdisZeroMemory(pTempStr, 512); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { if (apidx == 0) { NdisMoveMemory(pTempStr, "SSID=", strlen("SSID=")); offset = strlen(pTempStr); } else { offset = strlen(pTempStr); NdisMoveMemory(pTempStr + offset, ";", 1); offset += 1; } NdisMoveMemory(pTempStr + offset, pAd->ApCfg.MBSSID[apidx].Ssid, pAd->ApCfg.MBSSID[apidx].SsidLen); } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { UINT profile_idx = pAd->StaCfg.WscControl.WscProfile.ApplyProfileIdx; PWSC_CREDENTIAL pCredential = &pAd->StaCfg.WscControl.WscProfile.Profile[profile_idx]; NdisMoveMemory(pTempStr, "SSID=", strlen("SSID=")); offset = strlen(pTempStr); NdisMoveMemory(pTempStr + offset, pCredential->SSID.Ssid, pCredential->SSID.SsidLength); } #endif /* CONFIG_STA_SUPPORT */ } #ifdef CONFIG_AP_SUPPORT else { STRING item_str[10] = {0}; for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { snprintf(item_str, sizeof(item_str), "SSID%d", (apidx + 1)); if (rtstrstr(pTempStr, item_str)) { NdisZeroMemory(pTempStr, 512); NdisMoveMemory(pTempStr, item_str, strlen(item_str)); offset = strlen(pTempStr); NdisMoveMemory(pTempStr + offset, "=", 1); offset += 1; NdisMoveMemory(pTempStr + offset, pAd->ApCfg.MBSSID[apidx].Ssid, pAd->ApCfg.MBSSID[apidx].SsidLen); } NdisZeroMemory(item_str, 10); } } #endif /* CONFIG_AP_SUPPORT */ } VOID WscWriteWpaPskToDatFile( IN PRTMP_ADAPTER pAd, IN PSTRING pTempStr, IN BOOLEAN bNewFormat) { #ifdef CONFIG_AP_SUPPORT UCHAR apidx; #endif /* CONFIG_AP_SUPPORT */ PWSC_CTRL pWscControl; INT offset = 0; if (bNewFormat == FALSE) { NdisZeroMemory(pTempStr, 512); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl; if (apidx == 0) { NdisMoveMemory(pTempStr, "WPAPSK=", strlen("WPAPSK=")); offset = strlen(pTempStr); } else { offset = strlen(pTempStr); NdisMoveMemory(pTempStr + offset, ";", 1); offset += 1; } NdisMoveMemory(pTempStr + offset, pWscControl->WpaPsk, pWscControl->WpaPskLen); } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { pWscControl = &pAd->StaCfg.WscControl; NdisMoveMemory(pTempStr, "WPAPSK=", strlen("WPAPSK=")); if (pWscControl->WpaPskLen) { offset = strlen(pTempStr); NdisMoveMemory(pTempStr + offset, pWscControl->WpaPsk, pWscControl->WpaPskLen); } } #endif /* CONFIG_STA_SUPPORT */ } #ifdef CONFIG_AP_SUPPORT else { STRING item_str[10] = {0}; for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { snprintf(item_str, sizeof(item_str), "WPAPSK%d", (apidx + 1)); if (rtstrstr(pTempStr, item_str)) { pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl; NdisZeroMemory(pTempStr, 512); NdisMoveMemory(pTempStr, item_str, strlen(item_str)); offset = strlen(pTempStr); NdisMoveMemory(pTempStr + offset, "=", 1); offset += 1; NdisMoveMemory(pTempStr + offset, pWscControl->WpaPsk, pWscControl->WpaPskLen); } NdisZeroMemory(item_str, 10); } } #endif /* CONFIG_AP_SUPPORT */ } BOOLEAN WscCheckNonce( IN PRTMP_ADAPTER pAdapter, IN MLME_QUEUE_ELEM *pElem, IN BOOLEAN bFlag, IN PWSC_CTRL pWscControl) { USHORT Length; PUCHAR pData; USHORT WscType, WscLen, WscId; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscCheckNonce\n")); if (bFlag) { /* check Registrar Nonce */ WscId = WSC_ID_REGISTRAR_NONCE; DBGPRINT(RT_DEBUG_TRACE, ("check Registrar Nonce\n")); } else { /* check Enrollee Nonce */ WscId = WSC_ID_ENROLLEE_NONCE; DBGPRINT(RT_DEBUG_TRACE, ("check Enrollee Nonce\n")); } pData = pElem->Msg; Length = pElem->MsgLen; /* We have to look for WSC_IE_MSG_TYPE to classify M2 ~ M8, the remain size must large than 4 */ while (Length > 4) { WSC_IE TLV_Recv; char ZeroNonce[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; memcpy((UINT8 *)&TLV_Recv, pData, 4); WscType = be2cpu16(TLV_Recv.Type); WscLen = be2cpu16(TLV_Recv.Length); pData += 4; Length -= 4; if (WscType == WscId) { if (RTMPCompareMemory(pWscControl->RegData.SelfNonce, pData, 16) == 0) { DBGPRINT(RT_DEBUG_TRACE, ("Nonce match!!\n")); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscCheckNonce\n")); return TRUE; } else if (NdisEqualMemory(pData, ZeroNonce, 16)) { /* Intel external registrar will send WSC_NACK with enrollee nonce */ /* "10 1A 00 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00" */ /* when AP is configured and user selects not to configure AP. */ DBGPRINT(RT_DEBUG_TRACE, ("Zero Enrollee Nonce!!\n")); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscCheckNonce\n")); return TRUE; } } /* Offset to net WSC Ie */ pData += WscLen; Length -= WscLen; } DBGPRINT(RT_DEBUG_TRACE, ("Nonce mismatch!!\n")); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscCheckNonce\n")); return FALSE; } VOID WscGetRegDataPIN( IN PRTMP_ADAPTER pAdapter, IN UINT PinCode, IN PWSC_CTRL pWscControl) { UCHAR tempPIN[9] = {0}; if ((pWscControl->WscMode == WSC_PBC_MODE) || (pWscControl->WscMode == WSC_SMPBC_MODE)) pWscControl->WscPinCode = 0; else pWscControl->WscPinCode = PinCode; memset(pWscControl->RegData.PIN, 0, 8); if (pWscControl->WscPinCode == 0) { snprintf((PSTRING) tempPIN, sizeof(tempPIN), "00000000"); memcpy(pWscControl->RegData.PIN, tempPIN, 8); pWscControl->RegData.PinCodeLen = 8; } else { if ( pWscControl->WscPinCodeLen == 4) { UCHAR temp4PIN[5] = {0}; snprintf((PSTRING) temp4PIN, sizeof(temp4PIN), "%04u", pWscControl->WscPinCode); memcpy(pWscControl->RegData.PIN, temp4PIN, 4); pWscControl->RegData.PinCodeLen = 4; } else { snprintf((PSTRING) tempPIN, sizeof(tempPIN), "%08u", pWscControl->WscPinCode); memcpy(pWscControl->RegData.PIN, tempPIN, 8); pWscControl->RegData.PinCodeLen = 8; } } hex_dump("WscGetRegDataPIN - PIN", pWscControl->RegData.PIN, 8); } VOID WscEapActionDisabled( IN PRTMP_ADAPTER pAdapter, IN PWSC_CTRL pWscControl) { INT DataLen = 0; UCHAR *WscData = NULL; /*BOOLEAN Cancelled;*/ os_alloc_mem(NULL, &WscData, 256); if (WscData == NULL) return; DataLen = BuildMessageNACK(pAdapter, pWscControl, WscData); #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter) { if (pWscControl->EntryIfIdx & MIN_NET_DEVICE_FOR_APCLI) WscSendMessage(pAdapter, WSC_OPCODE_NACK, WscData, DataLen, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP); else WscSendMessage(pAdapter, WSC_OPCODE_NACK, WscData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAdapter) { if (ADHOC_ON(pAdapter) && (pWscControl->WscConfMode & WSC_REGISTRAR)) WscSendMessage(pAdapter, WSC_OPCODE_NACK, WscData, DataLen, pWscControl, STA_MODE, EAP_CODE_REQ); else WscSendMessage(pAdapter, WSC_OPCODE_NACK, WscData, DataLen, pWscControl, STA_MODE, EAP_CODE_RSP); } #endif /* CONFIG_STA_SUPPORT */ if (WscData) os_free_mem(NULL, WscData); /* RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); */ /* pWscControl->EapolTimerRunning = FALSE; */ } VOID WscGetConfigErrFromNack( IN PRTMP_ADAPTER pAdapter, IN MLME_QUEUE_ELEM *pElem, OUT USHORT *pConfigError) { USHORT Length = 0; PUCHAR pData; USHORT WscType, WscLen, ConfigError = 0; pData = pElem->Msg; Length = pElem->MsgLen; while (Length > 4) { WSC_IE TLV_Recv; memcpy((UINT8 *)&TLV_Recv, pData, 4); WscType = be2cpu16(TLV_Recv.Type); WscLen = be2cpu16(TLV_Recv.Length); pData += 4; Length -= 4; if (WscType == WSC_ID_CONFIG_ERROR) { NdisMoveMemory(&ConfigError, pData, sizeof(USHORT)); DBGPRINT(RT_DEBUG_TRACE, ("WSC_ID_CONFIG_ERROR: %d\n", ntohs(ConfigError))); *pConfigError = ntohs(ConfigError); return; } /* Offset to net WSC Ie */ pData += WscLen; Length -= WscLen; } DBGPRINT(RT_DEBUG_TRACE, ("WSC_ID_CONFIG_ERROR is missing\n")); } INT WscSetAuthMode( IN PRTMP_ADAPTER pAd, IN UCHAR CurOpMode, IN UCHAR apidx, IN PSTRING arg) { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { UINT32 i; if ((strcmp(arg, "WEPAUTO") == 0) || (strcmp(arg, "wepauto") == 0)) pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeAutoSwitch; else if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0)) pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeOpen; else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0)) pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeShared; else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0)) pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPAPSK; else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0)) pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA; else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0)) pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA2PSK; else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0)) pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA2; else if ((strcmp(arg, "WPA1WPA2") == 0) || (strcmp(arg, "wpa1wpa2") == 0)) pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA1WPA2; else if ((strcmp(arg, "WPAPSKWPA2PSK") == 0) || (strcmp(arg, "wpapskwpa2psk") == 0)) pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeWPA1PSKWPA2PSK; else { pAd->ApCfg.MBSSID[apidx].AuthMode = Ndis802_11AuthModeOpen; DBGPRINT(RT_DEBUG_TRACE, ("%s: Unknow AuthMode (%s), set AuthMode to OPEN\n", __FUNCTION__, arg)); } for (i=0; iMacTab.Content[i])) { pAd->MacTab.Content[i].PortSecured = WPA_802_1X_PORT_NOT_SECURED; } } pAd->ApCfg.MBSSID[apidx].PortSecured = WPA_802_1X_PORT_NOT_SECURED; /*RTMPMakeRSNIE(pAd, pAd->ApCfg.MBSSID[apidx].AuthMode, pAd->ApCfg.MBSSID[apidx].WepStatus, apidx); */ pAd->ApCfg.MBSSID[apidx].DefaultKeyId = 0; if(pAd->ApCfg.MBSSID[apidx].AuthMode >= Ndis802_11AuthModeWPA) pAd->ApCfg.MBSSID[apidx].DefaultKeyId = 0; DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) %s::(AuthMode=%d)\n", apidx, __FUNCTION__, pAd->ApCfg.MBSSID[apidx].AuthMode)); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (strcmp(arg, "WEPAUTO") == 0) pAd->StaCfg.AuthMode = Ndis802_11AuthModeAutoSwitch; else if (strcmp(arg, "OPEN") == 0) pAd->StaCfg.AuthMode = Ndis802_11AuthModeOpen; else if (strcmp(arg, "SHARED") == 0) pAd->StaCfg.AuthMode = Ndis802_11AuthModeShared; else if (strcmp(arg, "WPAPSK") == 0) pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPAPSK; else if (strcmp(arg, "WPANONE") == 0) pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone; else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "WPAPSKWPA2PSK") == 0)) pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2PSK; #ifdef WPA_SUPPLICANT_SUPPORT else if (strcmp(arg, "WPA") == 0) pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA; else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "WPA1WPA2") == 0)) pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPA2; #endif /* WPA_SUPPLICANT_SUPPORT */ else return FALSE; if ((pAd->StaCfg.BssType == BSS_ADHOC) && (pAd->StaCfg.AuthMode == Ndis802_11AuthModeWPAPSK)) { pAd->StaCfg.AuthMode = Ndis802_11AuthModeWPANone; } pAd->StaCfg.PortSecured = WPA_802_1X_PORT_NOT_SECURED; DBGPRINT(RT_DEBUG_TRACE, ("WscSetAuthMode::(AuthMode=%d)\n", pAd->StaCfg.AuthMode)); } #endif /* CONFIG_STA_SUPPORT */ return TRUE; } INT WscSetEncrypType( IN PRTMP_ADAPTER pAd, IN UCHAR CurOpMode, IN UCHAR apidx, IN PSTRING arg) { #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0)) pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPDisabled; else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0)) pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPEnabled; else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0)) pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption2Enabled; else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0)) pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption3Enabled; else if ((strcmp(arg, "TKIPAES") == 0) || (strcmp(arg, "tkipaes") == 0)) pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11Encryption4Enabled; else { pAd->ApCfg.MBSSID[apidx].WepStatus = Ndis802_11WEPDisabled; DBGPRINT(RT_DEBUG_TRACE, ("%s: Unknow EncrypType (%s), set EncrypType to NONE\n", __FUNCTION__, arg)); } if (pAd->ApCfg.MBSSID[apidx].WepStatus >= Ndis802_11Encryption2Enabled) pAd->ApCfg.MBSSID[apidx].DefaultKeyId = 0; /*RTMPMakeRSNIE(pAd, pAd->ApCfg.MBSSID[apidx].AuthMode, pAd->ApCfg.MBSSID[apidx].WepStatus, apidx); */ DBGPRINT(RT_DEBUG_TRACE, ("IF(ra%d) %s::(EncrypType=%d)\n", apidx, __FUNCTION__, pAd->ApCfg.MBSSID[apidx].WepStatus)); return TRUE; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (strcmp(arg, "NONE") == 0) { if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) return TRUE; /* do nothing */ pAd->StaCfg.WepStatus = Ndis802_11WEPDisabled; pAd->StaCfg.PairCipher = Ndis802_11WEPDisabled; pAd->StaCfg.GroupCipher = Ndis802_11WEPDisabled; } else if (strcmp(arg, "WEP") == 0) { if (pAd->StaCfg.AuthMode >= Ndis802_11AuthModeWPA) return TRUE; /* do nothing */ pAd->StaCfg.WepStatus = Ndis802_11WEPEnabled; pAd->StaCfg.PairCipher = Ndis802_11WEPEnabled; pAd->StaCfg.GroupCipher = Ndis802_11WEPEnabled; } else if (strcmp(arg, "TKIP") == 0) { if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) return TRUE; /* do nothing */ pAd->StaCfg.WepStatus = Ndis802_11Encryption2Enabled; pAd->StaCfg.PairCipher = Ndis802_11Encryption2Enabled; pAd->StaCfg.GroupCipher = Ndis802_11Encryption2Enabled; } else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "TKIPAES") == 0)) { if (pAd->StaCfg.AuthMode < Ndis802_11AuthModeWPA) return TRUE; /* do nothing */ pAd->StaCfg.WepStatus = Ndis802_11Encryption3Enabled; pAd->StaCfg.PairCipher = Ndis802_11Encryption3Enabled; pAd->StaCfg.GroupCipher = Ndis802_11Encryption3Enabled; } else return FALSE; DBGPRINT(RT_DEBUG_TRACE, ("WscSetEncrypType::(EncrypType=%d)\n", pAd->StaCfg.WepStatus)); } #endif /* CONFIG_STA_SUPPORT */ return TRUE; } #ifdef CONFIG_STA_SUPPORT USHORT WscGetAuthTypeFromStr( IN PSTRING arg) { if ((strcmp(arg, "OPEN") == 0) || (strcmp(arg, "open") == 0)) return WSC_AUTHTYPE_OPEN; else if ((strcmp(arg, "SHARED") == 0) || (strcmp(arg, "shared") == 0)) return WSC_AUTHTYPE_SHARED; else if ((strcmp(arg, "WPAPSK") == 0) || (strcmp(arg, "wpapsk") == 0)) return WSC_AUTHTYPE_WPAPSK; else if ((strcmp(arg, "WPA2PSK") == 0) || (strcmp(arg, "wpa2psk") == 0)) return WSC_AUTHTYPE_WPA2PSK; #ifdef WPA_SUPPLICANT_SUPPORT else if ((strcmp(arg, "WPA") == 0) || (strcmp(arg, "wpa") == 0)) return WSC_AUTHTYPE_WPA; else if ((strcmp(arg, "WPA2") == 0) || (strcmp(arg, "wpa2") == 0)) return WSC_AUTHTYPE_WPA2; #endif /* WPA_SUPPLICANT_SUPPORT */ else return 0; } USHORT WscGetEncrypTypeFromStr( IN PSTRING arg) { if ((strcmp(arg, "NONE") == 0) || (strcmp(arg, "none") == 0)) return WSC_ENCRTYPE_NONE; else if ((strcmp(arg, "WEP") == 0) || (strcmp(arg, "wep") == 0)) return WSC_ENCRTYPE_WEP; else if ((strcmp(arg, "TKIP") == 0) || (strcmp(arg, "tkip") == 0)) return WSC_ENCRTYPE_TKIP; else if ((strcmp(arg, "AES") == 0) || (strcmp(arg, "aes") == 0)) return WSC_ENCRTYPE_AES; else return 0; } #endif /* CONFIG_STA_SUPPORT */ /* ======================================================================== Routine Description: Push PBC from HW/SW Buttton Arguments: pAd - NIC Adapter pointer Return Value: None IRQL = DISPATCH_LEVEL Note: ======================================================================== */ VOID WscPushPBCAction( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl) { BOOLEAN Cancelled; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscPushPBCAction\n")); /* 0. PBC mode, disregard the SSID information, we have to get the current AP list */ /* and check the beacon for Push buttoned AP. */ /* 1. Cancel old timer to prevent use push continuously */ if (pWscControl->Wsc2MinsTimerRunning) { pWscControl->Wsc2MinsTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->Wsc2MinsTimer, &Cancelled); } if (pWscControl->WscScanTimerRunning) { pWscControl->WscScanTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscScanTimer, &Cancelled); } if (pWscControl->WscPBCTimerRunning) { pWscControl->WscPBCTimerRunning = FALSE; RTMPCancelTimer(&pWscControl->WscPBCTimer, &Cancelled); } /* Set WSC state to WSC_STATE_INIT */ pWscControl->WscState = WSC_STATE_START; pWscControl->WscStatus = STATUS_WSC_SCAN_AP; /* Init Registrar pair structures */ WscInitRegistrarPair(pAd, pWscControl, BSS0); /* For PBC, the PIN is all '0' */ WscGetRegDataPIN(pAd, pWscControl->WscPinCode, pWscControl); /* 2. Set 2 min timout routine */ RTMPSetTimer(&pWscControl->Wsc2MinsTimer, WSC_TWO_MINS_TIME_OUT); pWscControl->Wsc2MinsTimerRunning = TRUE; pWscControl->bWscTrigger = TRUE; /* start work */ /* 3. Call WscScan subroutine */ WscScanExec(pAd, pWscControl); /* 4. Set 10 second timer to invoke PBC connection actions. */ RTMPSetTimer(&pWscControl->WscPBCTimer, 10000); pWscControl->WscPBCTimerRunning = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("<----- WscPushPBCAction\n")); } /* ======================================================================== Routine Description: Doing an active scan with empty SSID, the scanened list will be processed in PBCexec or PINexec routines Arguments: pAd - NIC Adapter pointer Return Value: None IRQL = DISPATCH_LEVEL Note: ======================================================================== */ VOID WscScanExec( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl) { #ifdef WSC_LED_SUPPORT UCHAR WPSLEDStatus; #endif /* WSC_LED_SUPPORT */ /* Prevent infinite loop if conncet time out didn't stop the repeat scan */ if ((pWscControl->WscStatus == STATUS_WSC_FAIL) || (pWscControl->WscState == WSC_STATE_OFF)) return; DBGPRINT(RT_DEBUG_OFF, ("!!! WscScanExec !!!\n")); pWscControl->WscStatus = STATUS_WSC_SCAN_AP; #ifdef WSC_LED_SUPPORT /* The protocol is connecting to a partner. */ WPSLEDStatus = LED_WPS_IN_PROCESS; RTMPSetLED(pAd, WPSLEDStatus); #endif /* WSC_LED_SUPPORT */ #ifdef APCLI_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { ApSiteSurvey(pAd, NULL, SCAN_WSC_ACTIVE, FALSE); } #endif /* APCLI_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { pAd->StaCfg.bNotFirstScan = TRUE; StaSiteSurvey(pAd, NULL, SCAN_WSC_ACTIVE); } #endif /* CONFIG_STA_SUPPORT */ } /* ======================================================================== Routine Description: Doing PBC conenction verification, it will check current BSS list and find the correct number of PBC AP. If only 1 exists, it will start to make connection. Otherwise, it will set a scan timer to perform another scan for next PBC connection execution. Arguments: pAd - NIC Adapter pointer Return Value: None IRQL = DISPATCH_LEVEL Note: ======================================================================== */ BOOLEAN WscPBCExec( IN PRTMP_ADAPTER pAd, IN BOOLEAN bFromM2, IN PWSC_CTRL pWscControl) { #ifdef WSC_LED_SUPPORT UCHAR WPSLEDStatus; #endif /* WSC_LED_SUPPORT */ UCHAR CurOpMode = AP_MODE; if (pWscControl == NULL) return FALSE; #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (pWscControl->EntryIfIdx == BSS0) CurOpMode = STA_MODE; } #endif // CONFIG_STA_SUPPORT // DBGPRINT(RT_DEBUG_OFF, ("-----> WscPBCExec !!!\n")); /* 1. Search the qualified SSID from current SSID list */ WscPBCBssTableSort(pAd, pWscControl); /* 2. Check the qualified AP for connection, if more than 1 AP avaliable, report error. */ if (pWscControl->WscPBCBssCount != 1) { /* Set WSC state to WSC_FAIL */ pWscControl->WscState = WSC_STATE_FAIL; if (pWscControl->WscPBCBssCount== 0) { pWscControl->WscStatus = STATUS_WSC_PBC_NO_AP; #ifdef WSC_LED_SUPPORT /* Failed to find any partner. */ WPSLEDStatus = LED_WPS_ERROR; RTMPSetLED(pAd, WPSLEDStatus); #ifdef CONFIG_WIFI_LED_SUPPORT if (LED_MODE(pAd) == WPS_LED_MODE_SHARE) RTMPSetTimer(&pWscControl->WscLEDTimer, WSC_WPS_FAIL_WIFI_LED_TIMEOUT); #endif /* CONFIG_WIFI_LED_SUPPORT */ #endif /* WSC_LED_SUPPORT */ DBGPRINT(RT_DEBUG_OFF, ("WscPBCExec --> AP list is %d, wait for next time\n", pWscControl->WscPBCBssCount)); #ifdef CONFIG_STA_SUPPORT /* P2P PBC CLI doesn't need to check PBC overlapping, so we don't need to consider P2P case here. */ if (pAd->StaCfg.BssType == BSS_INFRA) #endif /* CONFIG_STA_SUPPORT */ { /* 2.1. Set 1 second timer to invoke another scan */ RTMPSetTimer(&pWscControl->WscScanTimer, 1000); pWscControl->WscScanTimerRunning = TRUE; } } else { pWscControl->WscStatus = STATUS_WSC_PBC_TOO_MANY_AP; RTMPSendWirelessEvent(pAd, IW_WSC_PBC_SESSION_OVERLAP, NULL, BSS0, 0); #ifdef WSC_LED_SUPPORT if (LED_MODE(pAd) == WPS_LED_MODE_9) /* WPS LED mode 9. */ { /* In case of the WPS LED mode 9, the UI would abort the connection attempt by making the RT_OID_802_11_WSC_SET_WPS_STATE_MACHINE_TERMINATION request. */ DBGPRINT(RT_DEBUG_TRACE, ("%s: Skip the WPS session overlap detected LED indication.\n", __FUNCTION__)); } else /* Other LED mode. */ { /* Session overlap detected. */ WPSLEDStatus = LED_WPS_SESSION_OVERLAP_DETECTED; RTMPSetLED(pAd, WPSLEDStatus); } #endif /* WSC_LED_SUPPORT */ /* 20101210 - According to the response from WFA: The station shall not continue scanning waiting for only one registrar to appear */ DBGPRINT(RT_DEBUG_TRACE, ("WscPBCExec --> AP list is %d, stop WPS process!\n", pWscControl->WscPBCBssCount)); WscStop(pAd, #ifdef CONFIG_AP_SUPPORT FALSE, #endif /* CONFIG_AP_SUPPORT */ pWscControl); pWscControl->WscConfMode = WSC_DISABLE; RTMPZeroMemory(pAd->MlmeAux.AutoReconnectSsid, MAX_LEN_OF_SSID); pAd->MlmeAux.AutoReconnectSsidLen = pAd->CommonCfg.SsidLen; RTMPMoveMemory(pAd->MlmeAux.AutoReconnectSsid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); } /* 2.2 We have to quit for now */ return FALSE; } if (bFromM2) return TRUE; /* 3. Now we got the intend AP, Set the WSC state and enqueue the SSID connection command */ pAd->MlmeAux.CurrReqIsFromNdis = FALSE; #ifdef CONFIG_STA_SUPPORT if (pAd->Mlme.CntlMachine.CurrState != CNTL_IDLE) { RTMP_MLME_RESET_STATE_MACHINE(pAd); DBGPRINT(RT_DEBUG_OFF, ("!!! WscPBCExec --> MLME busy, reset MLME state machine !!!\n")); } #endif /* CONFIG_STA_SUPPORT */ #ifdef CONFIG_STA_SUPPORT /* 4. Set WSC state to WSC_STATE_START */ if (CurOpMode == STA_MODE) { pWscControl->WscState = WSC_STATE_START; pWscControl->WscStatus = STATUS_WSC_START_ASSOC; } #endif /* CONFIG_STA_SUPPORT */ #ifdef WSC_LED_SUPPORT /* The protocol is connecting to a partner. */ WPSLEDStatus = LED_WPS_IN_PROCESS; RTMPSetLED(pAd, WPSLEDStatus); #endif /* WSC_LED_SUPPORT */ #ifdef APCLI_SUPPORT if (CurOpMode == AP_MODE) { STRING ChStr[5] = {0}; NdisMoveMemory(pWscControl->RegData.SelfInfo.MacAddr, pAd->ApCfg.ApCliTab[BSS0].CurrentAddress, MAC_ADDR_LEN); snprintf(ChStr, sizeof(ChStr), "%d", pAd->MlmeAux.Channel); Set_Channel_Proc(pAd, ChStr); /* bring apcli interface down first */ if(pAd->ApCfg.ApCliTab[BSS0].Enable == TRUE) { pAd->ApCfg.ApCliTab[BSS0].Enable = FALSE; ApCliIfDown(pAd); } pAd->ApCfg.ApCliTab[BSS0].Enable = TRUE; } #endif /* APCLI_SUPPORT */ #ifdef CONFIG_STA_SUPPORT /* Enqueue BSSID connection command */ if (CurOpMode == STA_MODE) { if (pAd->StaCfg.BssType == BSS_INFRA) { MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_BSSID, sizeof(NDIS_802_11_MAC_ADDRESS), (VOID *)&pWscControl->WscBssid[0], 0); } else { MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID, sizeof(NDIS_802_11_SSID), (VOID *)&pAd->StaCfg.WscControl.WscSsid, 0); } } #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_OFF, ("<----- WscPBCExec !!!\n")); return TRUE; } BOOLEAN WscBssWpsIESearchForPBC( PRTMP_ADAPTER pAd, PWSC_CTRL pWscControl, PBSS_ENTRY pInBss, UUID_BSSID_CH_INFO ApUuidBssid[], INT VarIeLen, PUCHAR pVar) { INT j = 0, Len = 0, idx = 0; BOOLEAN bFound, bSameAP, bSelReg; PUCHAR pData = NULL; PBEACON_EID_STRUCT pEid; USHORT DevicePasswordID; PWSC_IE pWscIE; UUID_BSSID_CH_INFO TmpInfo; UCHAR zeros16[16]= {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}; #ifdef IWSC_SUPPORT UINT8 RspType = 0; BOOLEAN bEntryAcceptable = FALSE; #endif // IWSC_SUPPORT // pData = pVar; bFound = FALSE; bSameAP = FALSE; bSelReg = FALSE; Len = VarIeLen; NdisZeroMemory(&TmpInfo, sizeof(UUID_BSSID_CH_INFO)); while ((Len > 0) && (bFound == FALSE)) { 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, WPS_OUI, 4) == FALSE) #ifdef IWSC_SUPPORT && (NdisEqualMemory(pEid->Octet, IWSC_OUI, 4) == FALSE) #endif // IWSC_SUPPORT // ) { /* 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 */ pWscIE = (PWSC_IE) pData; if (be2cpu16(pWscIE->Type) == WSC_ID_SEL_REGISTRAR) { hex_dump("SelReg:", pData, 5); bSelReg = pWscIE->Data[0]; DBGPRINT(RT_DEBUG_TRACE, ("bSelReg = %d\n", bSelReg)); } #ifdef IWSC_SUPPORT if ((pAd->OpMode == OPMODE_STA) && (pAd->StaCfg.BssType == BSS_ADHOC)) { if (be2cpu16(pWscIE->Type) == WSC_ID_RESP_TYPE) { RspType = pWscIE->Data[0]; if (RspType < WSC_MSGTYPE_REGISTRAR) { bFound = FALSE; break; } TmpInfo.RspType = RspType; } if (be2cpu16(pWscIE->Type) == WSC_ID_MAC_ADDR) { UCHAR mac_addr[MAC_ADDR_LEN]; RTMPMoveMemory(mac_addr, (pData+4), MAC_ADDR_LEN); if (NdisCmpMemory(pInBss->MacAddr, mac_addr, MAC_ADDR_LEN)) { bFound = FALSE; break; } } if (be2cpu16(pWscIE->Type) == WSC_ID_ENTRY_ACCEPTABLE) { hex_dump("EntryAcceptable:", pData, 5); bEntryAcceptable = pWscIE->Data[0]; DBGPRINT(RT_DEBUG_TRACE, ("bEntryAcceptable = %d\n", bEntryAcceptable)); } } #endif /* IWSC_SUPPORT */ /* Check for device password ID, PBC = 0x0004, SMPBC = 0x0006 */ if (be2cpu16(pWscIE->Type) == WSC_ID_DEVICE_PWD_ID) { /* Found device password ID */ #ifdef WINBOND /*The Winbond's platform will fail to retrive 2-bytes data, if use the original */ /*be2cpu16<-- */ DevicePasswordID = WINBON_GET16((PUCHAR)&pWscIE->Data[0]); #else DevicePasswordID = be2cpu16(get_unaligned((USHORT *)&pWscIE->Data[0])); /*DevicePasswordID = be2cpu16(*((USHORT *) &pWscIE->Data[0])); */ #endif /* WINBOND */ DBGPRINT(RT_DEBUG_TRACE, ("WscPBCBssTableSort : DevicePasswordID = 0x%04x\n", DevicePasswordID)); if (((pWscControl->WscMode == WSC_PBC_MODE) && (DevicePasswordID == DEV_PASS_ID_PBC)) || ((pWscControl->WscMode == WSC_SMPBC_MODE) && (DevicePasswordID == DEV_PASS_ID_SMPBC))) { /* Found matching PBC AP in current list, add it into table and add the count */ bFound = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("DPID=PBC Found --> \n")); DBGPRINT(RT_DEBUG_TRACE, ("# Bssid %02x:%02x:%02x:%02x:%02x:%02x\n", pInBss->Bssid[0], pInBss->Bssid[1], pInBss->Bssid[2], pInBss->Bssid[3], pInBss->Bssid[4], pInBss->Bssid[5])); if (pInBss->Channel > 14) TmpInfo.Band = WSC_RFBAND_50GHZ; else TmpInfo.Band = WSC_RFBAND_24GHZ; RTMPMoveMemory(&TmpInfo.Bssid[0], &pInBss->Bssid[0], MAC_ADDR_LEN); TmpInfo.Channel = pInBss->Channel; RTMPZeroMemory(&TmpInfo.Ssid[0], MAX_LEN_OF_SSID); RTMPMoveMemory(&TmpInfo.Ssid[0], &pInBss->Ssid[0], pInBss->SsidLen); TmpInfo.SsidLen = pInBss->SsidLen; } } /* UUID_E is optional for beacons, but mandatory for probe-request */ if (be2cpu16(pWscIE->Type) == WSC_ID_UUID_E) { /* Avoid error UUID-E storage from PIN mode */ RTMPMoveMemory(&TmpInfo.Uuid[0], (UCHAR *)(pData+4), 16); } /* 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(pWscIE->Length) + 4); Len -= (be2cpu16(pWscIE->Length) + 4); } #ifdef IWSC_SUPPORT if ((pAd->StaCfg.BssType == BSS_ADHOC) && (pWscControl->WscMode == WSC_SMPBC_MODE) && (bEntryAcceptable == FALSE) && bFound) { bFound = FALSE; } #endif /* IWSC_SUPPORT */ if ((bFound == TRUE) && (bSelReg == TRUE)) { if (pWscControl->WscPBCBssCount == 8) { break; } if (pWscControl->WscPBCBssCount > 0) { for (j = 0; j < pWscControl->WscPBCBssCount; j++) { if (RTMPCompareMemory(&ApUuidBssid[j].Uuid[0], &TmpInfo.Uuid[0], 16) == 0) { if (RTMPCompareMemory(&TmpInfo.Uuid[0], zeros16, 16) != 0) { /* Same UUID, indicate concurrent AP We can indicate 1 AP only. */ bSameAP = TRUE; break; } else if (RTMPCompareMemory(&TmpInfo.Uuid[0], zeros16, 16) == 0) { if (ApUuidBssid[j].Band != TmpInfo.Band) { if (RTMPCompareMemory(&ApUuidBssid[j].Bssid[0], &TmpInfo.Bssid[0], 5) == 0) { /* Zero UUID at different band, and first 5bytes of two BSSIDs are the same. Indicate concurrent AP, we can indicate 1 AP only. */ bSameAP = TRUE; break; } } } } else if ((RTMPCompareMemory(&TmpInfo.Uuid[0], zeros16, 16) == 0) || (RTMPCompareMemory(&ApUuidBssid[j].Uuid[0], zeros16, 16) == 0)) { if ((RTMPCompareMemory(&ApUuidBssid[j].Bssid[0], &TmpInfo.Bssid[0], 5) == 0) && (ApUuidBssid[j].Band != TmpInfo.Band)) { INT tmpDiff = (INT)(ApUuidBssid[j].Bssid[5] - TmpInfo.Bssid[5]); /* Zero UUID and Non-zero UUID at different band, and two BSSIDs are very close. Indicate concurrent AP, we can indicate 1 AP only. */ if ((tmpDiff <= 4) || (tmpDiff >= -4)) { bSameAP = TRUE; break; } } } } } if (bSameAP) { if ((pWscControl->WpsApBand == PREFERRED_WPS_AP_PHY_TYPE_2DOT4_G_FIRST) && (TmpInfo.Band == WSC_RFBAND_24GHZ) && (ApUuidBssid[j].Band != TmpInfo.Band)) { RTMPMoveMemory(&(ApUuidBssid[j].Bssid[0]), &TmpInfo.Bssid[0], MAC_ADDR_LEN); RTMPZeroMemory(&(ApUuidBssid[j].Ssid[0]), MAX_LEN_OF_SSID); RTMPMoveMemory(&(ApUuidBssid[j].Ssid[0]), &TmpInfo.Ssid[0], TmpInfo.SsidLen); ApUuidBssid[j].SsidLen = TmpInfo.SsidLen; ApUuidBssid[j].Channel = TmpInfo.Channel; } else if ((pWscControl->WpsApBand == PREFERRED_WPS_AP_PHY_TYPE_5_G_FIRST) && (TmpInfo.Band == WSC_RFBAND_50GHZ) && (ApUuidBssid[j].Band != TmpInfo.Band)) { RTMPMoveMemory(&(ApUuidBssid[j].Bssid[0]), &TmpInfo.Bssid[0], MAC_ADDR_LEN); RTMPZeroMemory(&(ApUuidBssid[j].Ssid[0]), MAX_LEN_OF_SSID); RTMPMoveMemory(&(ApUuidBssid[j].Ssid[0]), &TmpInfo.Ssid[0], TmpInfo.SsidLen); ApUuidBssid[j].SsidLen = TmpInfo.SsidLen; ApUuidBssid[j].Channel = TmpInfo.Channel; } } if (bSameAP == FALSE) { UCHAR index = pWscControl->WscPBCBssCount; /* Store UUID */ RTMPMoveMemory(&(ApUuidBssid[index].Uuid[0]), &TmpInfo.Uuid[0], 16); RTMPMoveMemory(&(ApUuidBssid[index].Bssid[0]), &pInBss->Bssid[0], MAC_ADDR_LEN); RTMPZeroMemory(&(ApUuidBssid[index].Ssid[0]), MAX_LEN_OF_SSID); RTMPMoveMemory(&(ApUuidBssid[index].Ssid[0]), &pInBss->Ssid[0], pInBss->SsidLen); ApUuidBssid[index].SsidLen = pInBss->SsidLen; ApUuidBssid[index].Channel = pInBss->Channel; if (ApUuidBssid[index].Channel > 14) ApUuidBssid[index].Band = WSC_RFBAND_50GHZ; else ApUuidBssid[index].Band = WSC_RFBAND_24GHZ; DBGPRINT(RT_DEBUG_ERROR, ("UUID-E= ")); for(idx=0; idx<16; idx++) DBGPRINT_RAW(RT_DEBUG_ERROR, ("%02x ", ApUuidBssid[index].Uuid[idx])); DBGPRINT(RT_DEBUG_ERROR, ("\n")); pWscControl->WscPBCBssCount++; } } } return (bFound && bSelReg); } /* ======================================================================== Routine Description: Find WSC PBC activated AP list Arguments: pAd - NIC Adapter pointer OutTab - Qualified AP BSS table Return Value: None IRQL = DISPATCH_LEVEL Note: All these constants are defined in wsc.h ======================================================================== */ VOID WscPBCBssTableSort( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl) { INT i; PBSS_ENTRY pInBss; /* UUID_BSSID_CH_INFO ApUuidBssid[8]; */ UUID_BSSID_CH_INFO *ApUuidBssid = NULL; BOOLEAN rv = FALSE; UCHAR CurOpMode = AP_MODE; #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (pWscControl->EntryIfIdx == BSS0) CurOpMode = STA_MODE; } #endif // CONFIG_STA_SUPPORT // #ifdef APCLI_SUPPORT if (CurOpMode == AP_MODE) pWscControl = &pAd->ApCfg.ApCliTab[BSS0].WscControl; #endif /* APCLI_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) pWscControl = &pAd->StaCfg.WscControl; #endif /* CONFIG_STA_SUPPORT */ if (pWscControl == NULL) return; /* allocate memory */ os_alloc_mem(NULL, (UCHAR **)&ApUuidBssid, sizeof(UUID_BSSID_CH_INFO)*8); if (ApUuidBssid == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("%s: Allocate memory fail!!!\n", __FUNCTION__)); return; } NdisZeroMemory(&ApUuidBssid[0], sizeof(UUID_BSSID_CH_INFO)); pWscControl->WscPBCBssCount = 0; for (i = 0; i < pAd->ScanTab.BssNr; i++) { /* BSS entry for VarIE processing */ pInBss = (PBSS_ENTRY) &pAd->ScanTab.BssEntry[i]; /* 1. Check VarIE length */ if (pInBss->VarIELen == 0) continue; #ifdef CONFIG_STA_SUPPORT if ((CurOpMode == STA_MODE) && (pInBss->BssType != pAd->StaCfg.BssType)) continue; #endif /* CONFIG_STA_SUPPORT */ /* 2. Search for WSC IE - 0xdd xx 00 50 f2 04 */ rv = WscBssWpsIESearchForPBC(pAd, pWscControl, pInBss, ApUuidBssid, pInBss->VarIELen, pInBss->VarIEs); if (rv == FALSE) { WscBssWpsIESearchForPBC(pAd, pWscControl, pInBss, ApUuidBssid, pInBss->VarIeFromProbeRspLen, pInBss->pVarIeFromProbRsp); } } if (pWscControl->WscPBCBssCount == 1) { RTMPZeroMemory(&pWscControl->WscSsid, sizeof(NDIS_802_11_SSID)); RTMPMoveMemory(pWscControl->WscSsid.Ssid, ApUuidBssid[0].Ssid, ApUuidBssid[0].SsidLen); pWscControl->WscSsid.SsidLength = ApUuidBssid[0].SsidLen; RTMPZeroMemory(pWscControl->WscBssid, MAC_ADDR_LEN); RTMPMoveMemory(pWscControl->WscBssid, ApUuidBssid[0].Bssid, MAC_ADDR_LEN); #ifdef CONFIG_STA_SUPPORT RTMPZeroMemory(pWscControl->WscPeerMAC, MAC_ADDR_LEN); RTMPMoveMemory(pWscControl->WscPeerMAC, ApUuidBssid[0].MacAddr, MAC_ADDR_LEN); #endif /* CONFIG_STA_SUPPORT */ pAd->MlmeAux.Channel = ApUuidBssid[0].Channel; #ifdef APCLI_SUPPORT if (CurOpMode == AP_MODE) { NdisZeroMemory(pAd->ApCfg.ApCliTab[BSS0].CfgSsid, MAX_LEN_OF_SSID); NdisMoveMemory(pAd->ApCfg.ApCliTab[BSS0].CfgSsid, ApUuidBssid[0].Ssid, ApUuidBssid[0].SsidLen); pAd->ApCfg.ApCliTab[BSS0].CfgSsidLen = (UCHAR)ApUuidBssid[0].SsidLen; } #endif /* APCLI_SUPPORT */ } if (ApUuidBssid != NULL) os_free_mem(NULL, ApUuidBssid); #ifdef IWSC_SUPPORT if (pWscControl->WscMode == WSC_SMPBC_MODE) DBGPRINT(RT_DEBUG_OFF, ("WscPBCBssTableSort : Total %d SMPBC Registrar Found\n", pWscControl->WscPBCBssCount)); else #endif /* IWSC_SUPPORT */ DBGPRINT(RT_DEBUG_OFF, ("WscPBCBssTableSort : Total %d PBC Registrar Found\n", pWscControl->WscPBCBssCount)); } VOID WscGenRandomKey( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl, INOUT PUCHAR pKey, INOUT PUSHORT pKeyLen) { UCHAR tempRandomByte = 0; UCHAR idx = 0; UCHAR keylen = 0; UCHAR retry = 0; NdisZeroMemory(pKey, 64); /* Hex Key 64 digital */ if(pWscControl->WscKeyASCII == 0) { UCHAR tmpStrB[3]; for (idx = 0; idx < 32; idx++) { NdisZeroMemory(&tmpStrB[0], sizeof(tmpStrB)); tempRandomByte = RandomByte(pAd); snprintf((PSTRING) &tmpStrB[0], 3, "%02x", tempRandomByte); NdisMoveMemory(pKey+(idx*2), &tmpStrB[0], 2); } *pKeyLen = 64; } else { /* ASCII Key, random length */ if(pWscControl->WscKeyASCII == 1) { do{ keylen = RandomByte(pAd); keylen = keylen % 64; if(retry++ > 20) keylen = 8; }while(keylen < 8); } else keylen = pWscControl->WscKeyASCII; /* Generate printable ASCII (decimal 33 to 126) */ for(idx = 0; idx < keylen; idx++) { tempRandomByte = RandomByte(pAd)%94+33; *(pKey+idx) = tempRandomByte; } *pKeyLen = keylen; } } VOID WscCreateProfileFromCfg( IN PRTMP_ADAPTER pAd, IN UCHAR OpMode, IN PWSC_CTRL pWscControl, OUT PWSC_PROFILE pWscProfile) { UCHAR apidx = (pWscControl->EntryIfIdx & 0x0F); USHORT authType = 0, encyType = 0; UCHAR WepKeyId = 0; PWSC_CREDENTIAL pCredential = NULL; UCHAR CurOpMode = AP_MODE; #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { if (pWscControl->EntryIfIdx == BSS0) CurOpMode = STA_MODE; } #endif // CONFIG_STA_SUPPORT // #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if ((OpMode & 0x0F) == AP_MODE) { /* AP needs to choose the STA's authType and encyType in two cases. 1. AP is unconfigurated (authType and encyType will be updated to mixed mode by WscWriteConfToPortCfg() ) 2. AP's authType is mixed mode, we should choose the suitable authType and encyType to STA STA's authType and encyType depend on WscSecurityMode flag */ if (((pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED ) || (pAd->ApCfg.MBSSID[apidx].AuthMode == Ndis802_11AuthModeWPA1PSKWPA2PSK)) && (OpMode & REGISTRAR_ACTION)) { switch (pAd->ApCfg.MBSSID[apidx].WscSecurityMode) { case WPAPSKTKIP: authType = WSC_AUTHTYPE_WPAPSK; encyType = WSC_ENCRTYPE_TKIP; break; case WPAPSKAES: authType = WSC_AUTHTYPE_WPAPSK; encyType = WSC_ENCRTYPE_AES; break; case WPA2PSKTKIP: authType = WSC_AUTHTYPE_WPA2PSK; encyType = WSC_ENCRTYPE_TKIP; break; case WPA2PSKAES: authType = WSC_AUTHTYPE_WPA2PSK; encyType = WSC_ENCRTYPE_AES; break; default: authType = (WSC_AUTHTYPE_WPAPSK | WSC_AUTHTYPE_WPA2PSK); encyType = (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES); break; } if (pWscControl->WscConfStatus == WSC_SCSTATE_CONFIGURED) { /* Although AuthMode is mixed mode, cipher maybe not mixed mode. We need to correct cipher here. */ if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption2Enabled) encyType = WSC_ENCRTYPE_TKIP; if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11Encryption3Enabled) encyType = WSC_ENCRTYPE_AES; } } else { authType = WscGetAuthType(pAd->ApCfg.MBSSID[apidx].AuthMode); encyType = WscGetEncryType(pAd->ApCfg.MBSSID[apidx].WepStatus); } WepKeyId = pAd->ApCfg.MBSSID[apidx].DefaultKeyId; } #ifdef APCLI_SUPPORT else if (OpMode == AP_CLIENT_MODE) { apidx = apidx & 0x0F; authType = WscGetAuthType(pAd->ApCfg.ApCliTab[apidx].AuthMode); encyType = WscGetEncryType(pAd->ApCfg.ApCliTab[apidx].WepStatus); WepKeyId = pAd->ApCfg.ApCliTab[apidx].DefaultKeyId; } #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { authType = WscGetAuthType(pAd->StaCfg.AuthMode); encyType = WscGetEncryType(pAd->StaCfg.WepStatus); WepKeyId = pAd->StaCfg.DefaultKeyId; } #endif /* CONFIG_STA_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("-----> WscGetDefaultProfileForM8\n")); pCredential = &pWscProfile->Profile[0]; /*Only support one credential now. 20070515 */ NdisZeroMemory(pCredential, sizeof(WSC_CREDENTIAL)); pWscProfile->ProfileCnt = 1; DBGPRINT(RT_DEBUG_TRACE, ("%s:: pWscControl->WscConfStatus = %d, OpMode = %d\n", __FUNCTION__, pWscControl->WscConfStatus, OpMode)); /* NewKey, NewKeyIndex for M8 */ if ((WSC_SCSTATE_UNCONFIGURED == pWscControl->WscConfStatus) && ((((OpMode & 0x0F) == AP_MODE) #ifdef CONFIG_STA_SUPPORT || (((OpMode & 0x0F) == STA_MODE) && (pAd->StaCfg.BssType == BSS_ADHOC)) #endif /* CONFIG_STA_SUPPORT */ ) && (OpMode & REGISTRAR_ACTION))) { pCredential->KeyIndex = 1; if ((OpMode & 0x0F) == STA_MODE) { #ifdef IWSC_TEST_SUPPORT if (pAd->StaCfg.IWscInfo.IWscDefaultSecurity == 1) { authType = WSC_AUTHTYPE_OPEN; encyType = WSC_ENCRTYPE_NONE; pCredential->KeyLength = 0; NdisZeroMemory(pCredential->Key, 64); } else if (pAd->StaCfg.IWscInfo.IWscDefaultSecurity == 2) { UCHAR idx; CHAR tempRandomByte; authType = WSC_AUTHTYPE_OPEN; encyType = WSC_ENCRTYPE_WEP; for(idx = 0; idx < 13; idx++) { tempRandomByte = RandomByte(pAd)%94+33; sprintf((PSTRING) pCredential->Key+idx, "%c", tempRandomByte); } pCredential->KeyLength = 13; } else #endif // IWSC_TEST_SUPPORT // { WscGenRandomKey(pAd, pWscControl, pCredential->Key, &pCredential->KeyLength); authType = WSC_AUTHTYPE_WPA2PSK; encyType = WSC_ENCRTYPE_AES; } } else WscGenRandomKey(pAd, pWscControl, pCredential->Key, &pCredential->KeyLength); } else { pCredential->KeyIndex = 1; pCredential->KeyLength = 0; NdisZeroMemory(pCredential->Key, 64); switch (encyType) { case WSC_ENCRTYPE_NONE: break; case WSC_ENCRTYPE_WEP: pCredential->KeyIndex = (WepKeyId + 1); if (((OpMode & 0x0F) == AP_MODE || (OpMode & 0x0F) == STA_MODE) && pAd->SharedKey[apidx][WepKeyId].KeyLen) { INT i; for (i=0; iSharedKey[apidx][WepKeyId].KeyLen; i++) { snprintf((PSTRING) pCredential->Key, 64, "%s%02x", pCredential->Key, pAd->SharedKey[apidx][WepKeyId].Key[i]); } pCredential->KeyLength = pAd->SharedKey[apidx][WepKeyId].KeyLen*2; } #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT else if ((OpMode == AP_CLIENT_MODE) && (pAd->ApCfg.ApCliTab[apidx].SharedKey[WepKeyId].KeyLen) && (CurOpMode == AP_MODE)) { INT i; for (i=0; iApCfg.ApCliTab[apidx].SharedKey[WepKeyId].KeyLen; i++) { snprintf((PSTRING) pCredential->Key, 64, "%s%02x", pCredential->Key, pAd->ApCfg.ApCliTab[apidx].SharedKey[WepKeyId].Key[i]); } pCredential->KeyLength = pAd->SharedKey[apidx][WepKeyId].KeyLen*2; } #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ break; case WSC_ENCRTYPE_TKIP: case WSC_ENCRTYPE_AES: case (WSC_ENCRTYPE_AES | WSC_ENCRTYPE_TKIP): pCredential->KeyLength = pWscControl->WpaPskLen; memcpy(pCredential->Key, pWscControl->WpaPsk, pWscControl->WpaPskLen); break; } } pCredential->AuthType = authType; pCredential->EncrType = encyType; #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if ((OpMode & 0x0F) == AP_MODE) { NdisMoveMemory(pCredential->MacAddr, pAd->ApCfg.MBSSID[apidx].Bssid, 6); if ((pWscControl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED) && (pWscControl->WscDefaultSsid.SsidLength > 0) && (pWscControl->WscDefaultSsid.SsidLength < 33)) { NdisMoveMemory(pCredential->SSID.Ssid, pWscControl->WscDefaultSsid.Ssid, pWscControl->WscDefaultSsid.SsidLength); pCredential->SSID.SsidLength = pWscControl->WscDefaultSsid.SsidLength; } else { NdisMoveMemory(pCredential->SSID.Ssid, pAd->ApCfg.MBSSID[apidx].Ssid, pAd->ApCfg.MBSSID[apidx].SsidLen); pCredential->SSID.SsidLength = pAd->ApCfg.MBSSID[apidx].SsidLen; } } #ifdef APCLI_SUPPORT else if (OpMode == AP_CLIENT_MODE) { NdisMoveMemory(pCredential->MacAddr, APCLI_ROOT_BSSID_GET(pAd, pAd->ApCfg.ApCliTab[apidx].MacTabWCID), 6); NdisMoveMemory(pCredential->SSID.Ssid, pAd->ApCfg.ApCliTab[apidx].Ssid, pAd->ApCfg.ApCliTab[apidx].SsidLen); pCredential->SSID.SsidLength = pAd->ApCfg.ApCliTab[apidx].SsidLen; } #endif /* APCLI_SUPPORT */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (pAd->StaCfg.BssType == BSS_INFRA) NdisMoveMemory(pCredential->MacAddr, pAd->CommonCfg.Bssid, 6); else NdisMoveMemory(pCredential->MacAddr, pAd->CurrentAddress, 6); NdisMoveMemory(pCredential->SSID.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); pCredential->SSID.SsidLength = pAd->CommonCfg.SsidLen; } #endif /* CONFIG_STA_SUPPORT */ #ifdef WSC_V2_SUPPORT if (pWscControl->WscV2Info.bEnableWpsV2 && (OpMode & REGISTRAR_ACTION)) NdisMoveMemory(pCredential->MacAddr, pWscControl->EntryAddr, 6); #endif /* WSC_V2_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscCreateProfileFromCfg\n")); } #ifdef CONFIG_AP_SUPPORT #ifdef APCLI_SUPPORT void WscWriteConfToApCliCfg( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl, IN PWSC_CREDENTIAL pCredential, IN BOOLEAN bEnrollee) { UCHAR CurApIdx = BSS0; APCLI_STRUCT *pApCliTab; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscWriteConfToApCliCfg\n")); CurApIdx = (pWscControl->EntryIfIdx & 0x0F); { pApCliTab = &pAd->ApCfg.ApCliTab[CurApIdx]; NdisZeroMemory(pApCliTab->Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(pApCliTab->Ssid, pCredential->SSID.Ssid, pCredential->SSID.SsidLength); pApCliTab->SsidLen = pCredential->SSID.SsidLength; NdisZeroMemory(pApCliTab->CfgSsid, MAX_LEN_OF_SSID); NdisMoveMemory(pApCliTab->CfgSsid, pCredential->SSID.Ssid, pCredential->SSID.SsidLength); pApCliTab->CfgSsidLen = pCredential->SSID.SsidLength; DBGPRINT(RT_DEBUG_TRACE, ("AuthType: %d, EncrType: %d\n", pCredential->AuthType, pCredential->EncrType)); if ((pCredential->AuthType == WSC_AUTHTYPE_WPAPSK) || (pCredential->AuthType == WSC_AUTHTYPE_WPA2PSK)) { if ((pCredential->EncrType != WSC_ENCRTYPE_TKIP) && (pCredential->EncrType != WSC_ENCRTYPE_AES)) { DBGPRINT(RT_DEBUG_TRACE, ("AuthType is WPAPSK or WPA2PAK.\n" "Get illegal EncrType(%d) from External Registrar, set EncrType to TKIP\n", pCredential->EncrType)); pCredential->EncrType = WSC_ENCRTYPE_TKIP; } } Set_ApCli_AuthMode_Proc(pAd, WscGetAuthTypeStr(pCredential->AuthType)); Set_ApCli_EncrypType_Proc(pAd, WscGetEncryTypeStr(pCredential->EncrType)); if (pCredential->EncrType != WSC_ENCRTYPE_NONE) { if (pCredential->EncrType & (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES)) { pApCliTab->DefaultKeyId = 0; if (pCredential->KeyLength >= 8 && pCredential->KeyLength <= 64) { pWscControl->WpaPskLen = (INT) pCredential->KeyLength; NdisZeroMemory(pWscControl->WpaPsk, 64); NdisMoveMemory(pWscControl->WpaPsk, pCredential->Key, pWscControl->WpaPskLen); RT_CfgSetWPAPSKKey(pAd, (PSTRING) pCredential->Key, pWscControl->WpaPskLen, (PUCHAR)pApCliTab->Ssid, pApCliTab->SsidLen, pApCliTab->PMK); DBGPRINT(RT_DEBUG_TRACE, ("WpaPskLen = %d\n", pWscControl->WpaPskLen)); } else { pWscControl->WpaPskLen = 0; DBGPRINT(RT_DEBUG_TRACE, ("WPAPSK: Invalid Key Length (%d)\n", pCredential->KeyLength)); } } else if (pCredential->EncrType == WSC_ENCRTYPE_WEP) { CHAR WepKeyId = 0; USHORT WepKeyLen = pCredential->KeyLength; WepKeyId = (pCredential->KeyIndex - 1); /* KeyIndex = 1 ~ 4 */ if ((WepKeyId >= 0) && (WepKeyId <=3)) { pApCliTab->DefaultKeyId = WepKeyId; /* 5 or 13 ASCII characters */ /* 10 or 26 Hex characters */ if (WepKeyLen == 5 || WepKeyLen == 13 || WepKeyLen == 10 || WepKeyLen == 26) { if (WepKeyLen == 5 || WepKeyLen == 13) { pApCliTab->SharedKey[WepKeyId].KeyLen = WepKeyLen; memcpy(pApCliTab->SharedKey[WepKeyId].Key, pCredential->Key,WepKeyLen); if (WepKeyLen == 5) pApCliTab->SharedKey[WepKeyId].CipherAlg = CIPHER_WEP64; else pApCliTab->SharedKey[WepKeyId].CipherAlg = CIPHER_WEP128; } else { pApCliTab->SharedKey[WepKeyId].KeyLen = (UCHAR) WepKeyLen/2; AtoH((PSTRING) pCredential->Key, pApCliTab->SharedKey[WepKeyId].Key, WepKeyLen/2); if (WepKeyLen == 10) pApCliTab->SharedKey[WepKeyId].CipherAlg = CIPHER_WEP64; else pApCliTab->SharedKey[WepKeyId].CipherAlg = CIPHER_WEP128; } } else DBGPRINT(RT_DEBUG_TRACE, ("WEP: Invalid Key Length (%d)\n", pCredential->KeyLength)); } else { DBGPRINT(RT_DEBUG_TRACE, ("Unsupport default key index (%d), use key Index 1.\n", WepKeyId)); pApCliTab->DefaultKeyId = WepKeyId = 0; } } } } if (pWscControl->WscProfile.ProfileCnt > 1) { pWscControl->WscProfileRetryTimerRunning = TRUE; RTMPSetTimer(&pWscControl->WscProfileRetryTimer, WSC_PROFILE_RETRY_TIME_OUT); } #ifdef P2P_SUPPORT if (P2P_CLI_ON(pAd)) { NdisZeroMemory(pAd->P2pCfg.SSID, MAX_LEN_OF_SSID); pAd->P2pCfg.SSIDLen = pCredential->SSID.SsidLength; NdisMoveMemory(pAd->P2pCfg.SSID, pCredential->SSID.Ssid, pAd->P2pCfg.SSIDLen); } #endif /* P2P_SUPPORT */ DBGPRINT(RT_DEBUG_TRACE, ("<----- WscWriteConfToApCliCfg\n")); } VOID WscApCliLinkDown( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl) { UCHAR apidx = (pWscControl->EntryIfIdx & 0x0F); UCHAR mac_addr[MAC_ADDR_LEN]; BOOLEAN apcliEn = pAd->ApCfg.ApCliTab[apidx].Enable; NdisMoveMemory(pWscControl->RegData.SelfInfo.MacAddr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, 6); /* bring apcli interface down first */ if(apcliEn == TRUE ) { pAd->ApCfg.ApCliTab[apidx].Enable = FALSE; ApCliIfDown(pAd); } pAd->ApCfg.ApCliTab[apidx].Enable = apcliEn; memcpy(mac_addr, pAd->ApCfg.ApCliTab[apidx].CurrentAddress, MAC_ADDR_LEN); pWscControl->WscStatus = STATUS_WSC_LINK_UP; pWscControl->bWscTrigger = TRUE; } #endif /* APCLI_SUPPORT */ #endif /* CONFIG_AP_SUPPORT */ VOID WpsSmProcess( IN PRTMP_ADAPTER pAd, IN MLME_QUEUE_ELEM *Elem) { int HeaderLen = LENGTH_802_11 + LENGTH_802_1_H + sizeof(IEEE8021X_FRAME) + sizeof(EAP_FRAME); PHEADER_802_11 pHeader; PMAC_TABLE_ENTRY pEntry = NULL; int apidx = MAIN_MBSSID; PWSC_CTRL pWpsCtrl = NULL; UCHAR CurOpMode = 0xFF; #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { CurOpMode = AP_MODE; } #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { CurOpMode = STA_MODE; } #ifdef P2P_SUPPORT if (Elem->OpMode == OPMODE_AP) CurOpMode = AP_MODE; #endif /* P2P_SUPPORT */ #endif // CONFIG_STA_SUPPORT // if (CurOpMode == 0xFF) { DBGPRINT(RT_DEBUG_WARN, ("Unkown OpMode (CurOpMode=0x%02x)\n", CurOpMode)); return; } else DBGPRINT(RT_DEBUG_TRACE, ("CurOpMode=0x%02x\n", CurOpMode)); pHeader = (PHEADER_802_11)Elem->Msg; if (Elem->MsgType == WSC_EAPOL_PACKET_MSG) { if ((pEntry = MacTableLookup(pAd, pHeader->Addr2))) apidx = pEntry->apidx; } #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { #ifdef APCLI_SUPPORT if (pEntry && IS_ENTRY_APCLI(pEntry)) pWpsCtrl = &pAd->ApCfg.ApCliTab[apidx].WscControl; else #endif /* APCLI_SUPPORT */ pWpsCtrl = &pAd->ApCfg.MBSSID[apidx].WscControl; } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) pWpsCtrl = &pAd->StaCfg.WscControl; #endif /* CONFIG_STA_SUPPORT */ if((Elem->MsgType == WSC_EAPOL_UPNP_MSG) && (Elem->MsgLen > HeaderLen)) { /*The WSC msg from UPnP daemon */ PUCHAR pData; UCHAR MacAddr[MAC_ADDR_LEN]= {0}; /* Skip the (802.11 + 802.1h + 802.1x + EAP) header */ pData = (PUCHAR) &Elem->Msg[HeaderLen]; Elem->MsgLen -= HeaderLen; /* The Addr1 of UPnP-Msg used to indicate the MAC address of the AP interface. Now always be ra0. */ NdisMoveMemory(MacAddr, pHeader->Addr1, MAC_ADDR_LEN); NdisMoveMemory(Elem->Msg, MacAddr, MAC_ADDR_LEN); NdisMoveMemory(Elem->Msg+6, pData, Elem->MsgLen); StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState); } else if (Elem->MsgType == WSC_EAPOL_START_MSG) StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState); else if (pEntry && (Elem->MsgType == WSC_EAPOL_PACKET_MSG)) { /* WSC_STATE_MACHINE can service only one station at one time */ PSTRING pData; PEAP_FRAME pEapFrame; /* Skip the EAP LLC header */ pData = (PSTRING) &Elem->Msg[LENGTH_802_11 + LENGTH_802_1_H]; pEapFrame = (PEAP_FRAME)(pData + sizeof(IEEE8021X_FRAME)); pData += sizeof(IEEE8021X_FRAME) + sizeof(EAP_FRAME); DBGPRINT(RT_DEBUG_ERROR, ("%s:: EAPOL Packet. Code = %d. Type = %d\n", __FUNCTION__, pEapFrame->Code, pEapFrame->Type)); if (pEapFrame->Code == EAP_CODE_FAIL) { /* EAP-Fail */ STRING fail_data[] = "EAP_FAIL"; NdisMoveMemory(Elem->Msg, pHeader->Addr2, MAC_ADDR_LEN); NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, fail_data, strlen(fail_data)); Elem->MsgLen = strlen(fail_data); StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState); return; } else if ((pEapFrame->Code == EAP_CODE_REQ) && (pEapFrame->Type == EAP_TYPE_ID)) { /* EAP-Req (Identity) */ STRING id_data[] = "hello"; pWpsCtrl->lastId = pEapFrame->Id; NdisMoveMemory(Elem->Msg, pHeader->Addr2, MAC_ADDR_LEN); NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, id_data, strlen(id_data)); Elem->MsgLen = strlen(id_data); StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState); return; } else if ((pEapFrame->Code == EAP_CODE_REQ) && (pEapFrame->Type == EAP_TYPE_WSC)) { /* EAP-Req (Messages) */ if (Elem->MsgLen <= HeaderLen) { DBGPRINT(RT_DEBUG_ERROR, ("Elem->MsgLen(%ld) <= HeaderLen(%d) !!\n", Elem->MsgLen, HeaderLen)); return; } pWpsCtrl->lastId = pEapFrame->Id; Elem->MsgLen -= (LENGTH_802_11 + LENGTH_802_1_H + sizeof(IEEE8021X_FRAME) + sizeof(EAP_FRAME)); if (WscCheckWSCHeader((PUCHAR)pData)) { PWSC_FRAME pWsc = (PWSC_FRAME) pData; NdisMoveMemory(Elem->Msg, pHeader->Addr2, MAC_ADDR_LEN); if (pWsc->OpCode == WSC_OPCODE_FRAG_ACK) { /* Send rest WSC frag data */ STRING wsc_frag_ack[] = "WSC_FRAG_ACK"; NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, wsc_frag_ack, strlen(wsc_frag_ack)); Elem->MsgLen = strlen(wsc_frag_ack); StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState); } else if (pWsc->OpCode == WSC_OPCODE_START) { STRING wsc_start[] = "WSC_START"; NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, wsc_start, strlen(wsc_start)); Elem->MsgLen = strlen(wsc_start); StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState); } else { if (pWsc->Flags & WSC_MSG_FLAG_LF) { pData += (sizeof(WSC_FRAME) + 2); Elem->MsgLen -= (sizeof(WSC_FRAME) + 2); } else { pData += sizeof(WSC_FRAME); Elem->MsgLen -= sizeof(WSC_FRAME); } if ((pWpsCtrl->WscRxBufLen + Elem->MsgLen) < (MGMT_DMA_BUFFER_SIZE-6)) { NdisMoveMemory((pWpsCtrl->pWscRxBuf + pWpsCtrl->WscRxBufLen), pData, Elem->MsgLen); pWpsCtrl->WscRxBufLen += Elem->MsgLen; } #ifdef WSC_V2_SUPPORT if (pWsc->Flags & WSC_MSG_FLAG_MF) WscSendEapFragAck(pAd, pWpsCtrl, pEntry); else #endif /* WSC_V2_SUPPORT */ { NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, pWpsCtrl->pWscRxBuf, pWpsCtrl->WscRxBufLen); Elem->MsgLen = pWpsCtrl->WscRxBufLen; StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState); pWpsCtrl->WscRxBufLen = 0; NdisZeroMemory(pWpsCtrl->pWscRxBuf, MGMT_DMA_BUFFER_SIZE); } } return; } else { DBGPRINT(RT_DEBUG_TRACE, ("ERROR: WscCheckWSCHeader() return FALSE!\n")); return; } } if (Elem->MsgLen <= HeaderLen) { DBGPRINT(RT_DEBUG_ERROR, ("Elem->MsgLen(%ld) <= HeaderLen(%d) !!\n", Elem->MsgLen, HeaderLen)); return; } Elem->MsgLen -= (LENGTH_802_11 + LENGTH_802_1_H + sizeof(IEEE8021X_FRAME) + sizeof(EAP_FRAME)); NdisMoveMemory(Elem->Msg, pHeader->Addr2, MAC_ADDR_LEN); if (IS_ENTRY_CLIENT(pEntry) && (pEapFrame->Code == EAP_CODE_RSP) && (pEapFrame->Type == EAP_TYPE_ID)) { if (strstr(pData, "SimpleConfig")) { /* EAP-Rsp (Identity) */ NdisMoveMemory(Elem->Msg+6, pData, Elem->MsgLen); StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState); return; } else { BOOLEAN Cancelled; DBGPRINT(RT_DEBUG_TRACE, ("RTMPCancelTimer EapolTimer!!\n")); NdisZeroMemory(pWpsCtrl->EntryAddr, MAC_ADDR_LEN); pWpsCtrl->EapolTimerRunning = FALSE; RTMPCancelTimer(&pWpsCtrl->EapolTimer, &Cancelled); return; } } else { if (WscCheckWSCHeader((PUCHAR) pData)) { /* EAP-Rsp (Messages) */ PWSC_FRAME pWsc = (PWSC_FRAME) pData; if (pWsc->OpCode == WSC_OPCODE_FRAG_ACK) { /* Send rest frag data */ STRING wsc_frag_ack[] = "WSC_FRAG_ACK"; NdisMoveMemory(Elem->Msg+MAC_ADDR_LEN, wsc_frag_ack, strlen(wsc_frag_ack)); Elem->MsgLen = strlen(wsc_frag_ack); StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState); } else { if (pWsc->Flags & WSC_MSG_FLAG_LF) { pData += (sizeof(WSC_FRAME) + 2); Elem->MsgLen -= (sizeof(WSC_FRAME) + 2); } else { pData += sizeof(WSC_FRAME); Elem->MsgLen -= sizeof(WSC_FRAME); } if ((pWpsCtrl->WscRxBufLen + Elem->MsgLen) < (MGMT_DMA_BUFFER_SIZE-6)) { NdisMoveMemory((pWpsCtrl->pWscRxBuf + pWpsCtrl->WscRxBufLen), pData, Elem->MsgLen); pWpsCtrl->WscRxBufLen += Elem->MsgLen; } #ifdef WSC_V2_SUPPORT if (pWsc->Flags & WSC_MSG_FLAG_MF) WscSendEapFragAck(pAd, pWpsCtrl, pEntry); else #endif /* WSC_V2_SUPPORT */ { //NdisMoveMemory(Elem->Msg+6, pData, Elem->MsgLen); NdisMoveMemory(Elem->Msg+6, pWpsCtrl->pWscRxBuf, pWpsCtrl->WscRxBufLen); Elem->MsgLen = pWpsCtrl->WscRxBufLen; StateMachinePerformAction(pAd, &pAd->Mlme.WscMachine, Elem, pAd->Mlme.WscMachine.CurrState); pWpsCtrl->WscRxBufLen = 0; NdisZeroMemory(pWpsCtrl->pWscRxBuf, MGMT_DMA_BUFFER_SIZE); } } return; } else { DBGPRINT(RT_DEBUG_TRACE, ("ERROR: WscCheckWSCHeader() return FALSE!\n")); return; } } } else DBGPRINT(RT_DEBUG_WARN, ("Unknow Message Type (=%lu)\n", Elem->MsgType)); } #ifdef CONFIG_AP_SUPPORT INT WscGetConfWithoutTrigger( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWscControl, IN BOOLEAN bFromUPnP) { INT WscMode; INT IsAPConfigured; PWSC_UPNP_NODE_INFO pWscUPnPNodeInfo; UCHAR apIdx; #ifdef LINUX #endif /* LINUX */ /* TODO: Is it possible ApCli call this fucntion?? */ apIdx = (pWscControl->EntryIfIdx & 0x0F); IsAPConfigured = pWscControl->WscConfStatus; pWscUPnPNodeInfo = &pWscControl->WscUPnPNodeInfo; if (pWscControl->WscConfMode == WSC_DISABLE) { pWscControl->bWscTrigger = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("WscGetConfForUpnp:: WPS is disabled.\n")); return FALSE; } if (bFromUPnP) WscStop(pAd, FALSE, pWscControl); if (pWscControl->WscMode == 1) WscMode = DEV_PASS_ID_PIN; else WscMode = DEV_PASS_ID_PBC; WscBuildBeaconIE(pAd, IsAPConfigured, TRUE, WscMode, pWscControl->WscConfigMethods, (pWscControl->EntryIfIdx & 0x0F), NULL, 0, AP_MODE); WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, TRUE, WscMode, pWscControl->WscConfigMethods, pWscControl->EntryIfIdx, NULL, 0, AP_MODE); APUpdateBeaconFrame(pAd, pWscControl->EntryIfIdx & 0x0F); /* 2mins time-out timer */ RTMPSetTimer(&pWscControl->Wsc2MinsTimer, WSC_TWO_MINS_TIME_OUT); pWscControl->Wsc2MinsTimerRunning = TRUE; pWscControl->WscStatus = STATUS_WSC_LINK_UP; if (bFromUPnP) WscSendUPnPConfReqMsg(pAd, apIdx, (PUCHAR)pAd->ApCfg.MBSSID[apIdx].Ssid, pAd->ApCfg.MBSSID[apIdx].Bssid, 3, 0, AP_MODE); pWscControl->bWscTrigger = TRUE; pWscControl->bWscAutoTigeer = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("%s:: trigger WSC state machine\n", __FUNCTION__)); return TRUE; } #endif /* CONFIG_AP_SUPPORT */ VOID WscSendNACK( IN PRTMP_ADAPTER pAdapter, IN MAC_TABLE_ENTRY *pEntry, IN PWSC_CTRL pWscControl) { INT DataLen = 0; PUCHAR pWscData = NULL; BOOLEAN Cancelled; UCHAR CurOpMode = AP_MODE; #ifdef CONFIG_STA_SUPPORT if ((pAdapter->OpMode == OPMODE_STA) && (pWscControl->EntryIfIdx == BSS0)) CurOpMode = STA_MODE; #endif /* CONFIG_STA_SUPPORT */ os_alloc_mem(NULL, (UCHAR **)&pWscData, WSC_MAX_DATA_LEN); if (pWscData == NULL) { DBGPRINT(RT_DEBUG_TRACE, ("WscSendNACK:: WscData Allocate failed!\n")); return; } NdisZeroMemory(pWscData, WSC_MAX_DATA_LEN); DataLen = BuildMessageNACK(pAdapter, pWscControl, pWscData); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (pEntry && (IS_ENTRY_APCLI(pEntry) #ifdef P2P_SUPPORT || (P2P_CLI_ON(pAdapter)) #endif /* P2P_SUPPORT */ ) ) WscSendMessage(pAdapter, WSC_OPCODE_NACK, pWscData, DataLen, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP); else WscSendMessage(pAdapter, WSC_OPCODE_NACK, pWscData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { if (ADHOC_ON(pAdapter) && (pWscControl->WscConfMode & WSC_REGISTRAR)) WscSendMessage(pAdapter, WSC_OPCODE_NACK, pWscData, DataLen, pWscControl, STA_MODE, EAP_CODE_REQ); else WscSendMessage(pAdapter, WSC_OPCODE_NACK, pWscData, DataLen, pWscControl, STA_MODE, EAP_CODE_RSP); } #endif /* CONFIG_STA_SUPPORT */ RTMPCancelTimer(&pWscControl->EapolTimer, &Cancelled); pWscControl->EapolTimerRunning = FALSE; pWscControl->RegData.ReComputePke = 1; if (pWscData) os_free_mem(NULL, pWscData); } #ifdef WSC_INCLUDED VOID WscCheckWpsIeFromWpsAP( IN PRTMP_ADAPTER pAd, IN PEID_STRUCT pEid, OUT PUSHORT pDPIDFromAP) { PUCHAR pData; SHORT Len = 0; PWSC_IE pWscIE; USHORT DevicePasswordID; if (NdisEqualMemory(pEid->Octet, WPS_OUI, 4) #ifdef IWSC_SUPPORT || NdisEqualMemory(pEid->Octet, IWSC_OUI, 4) #endif // IWSC_SUPPORT // ) { pData = (PUCHAR) pEid->Octet + 4; Len = (SHORT)(pEid->Len - 4); while (Len > 0) { WSC_IE WscIE; NdisMoveMemory(&WscIE, pData, sizeof(WSC_IE)); /* Check for WSC IEs */ pWscIE = &WscIE; /* Check for device password ID, PIN = 0x0000, PBC = 0x0004 */ if (pDPIDFromAP && be2cpu16(pWscIE->Type) == WSC_ID_DEVICE_PWD_ID) { /* Found device password ID */ NdisMoveMemory(&DevicePasswordID, pData + 4, sizeof(DevicePasswordID)); DevicePasswordID = be2cpu16(DevicePasswordID); DBGPRINT(RT_DEBUG_INFO, ("WscCheckWpsIeFromWpsAP : DevicePasswordID = 0x%04x\n", DevicePasswordID)); if (DevicePasswordID == DEV_PASS_ID_PIN) { /* PIN */ *pDPIDFromAP = DEV_PASS_ID_PIN; } else if (DevicePasswordID == DEV_PASS_ID_PBC) { /* PBC */ *pDPIDFromAP = DEV_PASS_ID_PBC; } } #ifdef CONFIG_STA_SUPPORT #endif /* CONFIG_STA_SUPPORT */ /* 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(pWscIE->Length) + 4); Len -= (be2cpu16(pWscIE->Length) + 4); } } return; } #endif /* WSC_INCLUDED */ #ifdef CONFIG_STA_SUPPORT VOID WscLinkDown( IN PRTMP_ADAPTER pAd) { if (INFRA_ON(pAd) && OPSTATUS_TEST_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED)) { MLME_DISASSOC_REQ_STRUCT DisassocReq; DBGPRINT(RT_DEBUG_TRACE, ("WscLinkDown(): Disassociate with current WPS AP...\n")); DisassocParmFill(pAd, &DisassocReq, pAd->CommonCfg.Bssid, REASON_DISASSOC_STA_LEAVING); MlmeEnqueue(pAd, ASSOC_STATE_MACHINE, MT2_MLME_DISASSOC_REQ, sizeof(MLME_DISASSOC_REQ_STRUCT), &DisassocReq, 0); pAd->Mlme.CntlMachine.CurrState = CNTL_WAIT_DISASSOC; pAd->MlmeAux.CurrReqIsFromNdis = TRUE; RTMP_MLME_HANDLER(pAd); } if (pAd->StaCfg.WscControl.WscConfMode != WSC_DISABLE) { #ifdef WSC_LED_SUPPORT UCHAR WPSLEDStatus; /* The protocol is connecting to a partner. */ WPSLEDStatus = LED_WPS_IN_PROCESS; RTMPSetLED(pAd, WPSLEDStatus); #endif /* WSC_LED_SUPPORT */ #ifdef IWSC_SUPPORT /* We need to send EAPOL_Start again to trigger WPS process */ if (pAd->StaCfg.BssType == BSS_ADHOC) { pAd->StaCfg.IWscInfo.bSendEapolStart = FALSE; pAd->StaCfg.WscControl.WscState = WSC_STATE_LINK_UP; pAd->StaCfg.WscControl.WscStatus = STATUS_WSC_LINK_UP; WscSendEapolStart(pAd, pAd->StaCfg.WscControl.WscPeerMAC, STA_MODE); } else #endif /* IWSC_SUPPORT */ pAd->StaCfg.WscControl.WscState = WSC_STATE_START; } else { pAd->bConfigChanged = TRUE; pAd->StaCfg.WscControl.bWscTrigger = FALSE; if (pAd->StaCfg.BssType == BSS_INFRA) { BssTableDeleteEntry(&pAd->ScanTab, pAd->CommonCfg.Bssid, pAd->CommonCfg.Channel); pAd->MlmeAux.SsidBssTab.BssNr = 0; MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_BSSID, MAC_ADDR_LEN, pAd->MlmeAux.Bssid, 0); RTMP_MLME_HANDLER(pAd); } #ifdef IWSC_SUPPORT else /* BSS_ADHOC */ { NDIS_802_11_SSID Ssid; if (pAd->StaCfg.IWscInfo.bReStart) { pAd->StaCfg.bNotFirstScan = FALSE; pAd->StaCfg.bAutoConnectByBssid = FALSE; pAd->StaCfg.IWscInfo.bReStart = FALSE; pAd->StaCfg.IWscInfo.bDoNotChangeBSSID = TRUE; LinkDown(pAd, FALSE); OPSTATUS_CLEAR_FLAG(pAd, fOP_STATUS_MEDIA_STATE_CONNECTED); RTMP_IndicateMediaState(pAd, NdisMediaStateDisconnected); pAd->ExtraInfo = GENERAL_LINK_DOWN; if (pAd->StaCfg.WscControl.WscStatus != STATUS_WSC_CONFIGURED) { Ssid.SsidLength = pAd->CommonCfg.SsidLen; NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(Ssid.Ssid, pAd->CommonCfg.Ssid, pAd->CommonCfg.SsidLen); } else { Ssid.SsidLength = pAd->MlmeAux.SsidLen; NdisZeroMemory(Ssid.Ssid, MAX_LEN_OF_SSID); NdisMoveMemory(Ssid.Ssid, pAd->MlmeAux.Ssid, Ssid.SsidLength); } MlmeEnqueue(pAd, MLME_CNTL_STATE_MACHINE, OID_802_11_SSID, sizeof(NDIS_802_11_SSID), (VOID *)&Ssid, 0); RTMP_MLME_HANDLER(pAd); } MlmeEnqueue(pAd, IWSC_STATE_MACHINE, IWSC_MT2_MLME_STOP, 0, NULL, 0); RTMP_MLME_HANDLER(pAd); } #endif /* IWSC_SUPPORT */ } pAd->StaCfg.WscControl.RegData.ReComputePke = 1; } ULONG WscSearchWpsApBySSID( IN PRTMP_ADAPTER pAd, IN PUCHAR pSsid, IN UCHAR SsidLen, IN INT WscMode) { UCHAR i; USHORT DesiredDPID; BSS_ENTRY *pBss; PWSC_CTRL pWscControl = &pAd->StaCfg.WscControl; if (WscMode == WSC_PBC_MODE) DesiredDPID = DEV_PASS_ID_PBC; else DesiredDPID = DEV_PASS_ID_PIN; for (i = 0; i < pAd->ScanTab.BssNr; i++) { pBss = &pAd->ScanTab.BssEntry[i]; if (SSID_EQUAL(pSsid, SsidLen, pBss->Ssid, pBss->SsidLen) && pBss->WpsAP && ((pBss->WscDPIDFromWpsAP == DesiredDPID) || (DesiredDPID == DEV_PASS_ID_PIN))) { if ((pWscControl->WpsApBand == PREFERRED_WPS_AP_PHY_TYPE_5_G_FIRST) && (pBss->Channel <= 14)) continue; else if ((pWscControl->WpsApBand == PREFERRED_WPS_AP_PHY_TYPE_2DOT4_G_FIRST) && (pBss->Channel > 14)) continue; else return (ULONG)i; } } return (ULONG)BSS_NOT_FOUND; } #endif /* CONFIG_STA_SUPPORT */ VOID WscPBCSessionOverlapCheck( IN PRTMP_ADAPTER pAd) { ULONG now; PWSC_STA_PBC_PROBE_INFO pWscStaPbcProbeInfo = &pAd->CommonCfg.WscStaPbcProbeInfo; pAd->CommonCfg.WscPBCOverlap = FALSE; if (pWscStaPbcProbeInfo->WscPBCStaProbeCount > 1) { UCHAR i; for (i = 0; i < MAX_PBC_STA_TABLE_SIZE; i++) { NdisGetSystemUpTime(&now); if (pWscStaPbcProbeInfo->Valid[i] && RTMP_TIME_AFTER(now, pWscStaPbcProbeInfo->ReciveTime[i] + 120*OS_HZ)) { NdisZeroMemory(&(pWscStaPbcProbeInfo->StaMacAddr[i][0]), MAC_ADDR_LEN); pWscStaPbcProbeInfo->ReciveTime[i] = 0; pWscStaPbcProbeInfo->Valid[i] = FALSE; pWscStaPbcProbeInfo->WscPBCStaProbeCount--; } } if (pWscStaPbcProbeInfo->WscPBCStaProbeCount > 1) pAd->CommonCfg.WscPBCOverlap = TRUE; } DBGPRINT(RT_DEBUG_TRACE, ("WscPBCSessionOverlapCheck : WscPBCStaProbeCount = %d\n", pWscStaPbcProbeInfo->WscPBCStaProbeCount)); return; } VOID WscPBC_DPID_FromSTA( IN PRTMP_ADAPTER pAd, IN PUCHAR pMacAddr) { INT Index = 0; UCHAR tab_idx; BOOLEAN bAddEntry = FALSE; ULONG now; PWSC_STA_PBC_PROBE_INFO pWscStaPbcProbeInfo = &pAd->CommonCfg.WscStaPbcProbeInfo; NdisGetSystemUpTime(&now); if (pWscStaPbcProbeInfo->WscPBCStaProbeCount == 0) bAddEntry = TRUE; else { for (tab_idx = 0; tab_idx < MAX_PBC_STA_TABLE_SIZE; tab_idx++) { if (NdisEqualMemory(pMacAddr, pWscStaPbcProbeInfo->StaMacAddr[tab_idx], MAC_ADDR_LEN)) { pWscStaPbcProbeInfo->ReciveTime[tab_idx] = now; return; } } for (tab_idx = 0; tab_idx < MAX_PBC_STA_TABLE_SIZE; tab_idx++) { if (RTMP_TIME_AFTER(now, pWscStaPbcProbeInfo->ReciveTime[tab_idx] + 120*OS_HZ) || NdisEqualMemory(pWscStaPbcProbeInfo->StaMacAddr[tab_idx], &ZERO_MAC_ADDR[0], MAC_ADDR_LEN)) { if (pWscStaPbcProbeInfo->Valid[tab_idx] == FALSE) { Index = tab_idx; bAddEntry = TRUE; break; } else { pWscStaPbcProbeInfo->ReciveTime[tab_idx] = now; NdisMoveMemory(pWscStaPbcProbeInfo->StaMacAddr[tab_idx], pMacAddr, MAC_ADDR_LEN); return; } } } } if (bAddEntry) { pWscStaPbcProbeInfo->WscPBCStaProbeCount++; pWscStaPbcProbeInfo->ReciveTime[Index] = now; pWscStaPbcProbeInfo->Valid[Index] = TRUE; NdisMoveMemory(pWscStaPbcProbeInfo->StaMacAddr[Index], pMacAddr, MAC_ADDR_LEN); } } void WscWriteConfToDatFile( IN PRTMP_ADAPTER pAd, IN UCHAR CurOpMode) { char *cfgData = 0; PSTRING fileName = NULL; RTMP_OS_FD file_r, file_w; RTMP_OS_FS_INFO osFSInfo; LONG rv, fileLen = 0; char *offset = 0; PSTRING pTempStr = 0; #ifdef CONFIG_AP_SUPPORT INT index = 0; UCHAR apidx = (pAd->WriteWscCfgToDatFile & 0x0F); #endif /* CONFIG_AP_SUPPORT */ PWSC_CTRL pWscControl = NULL; PWSC_CREDENTIAL pCredentail = NULL; STRING WepKeyName[MAX_WEPKEYNAME_LEN] = {0}; STRING WepKeyFormatName[MAX_WEPKEYNAME_LEN] = {0}; INT tempStrLen = 0; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscWriteConfToDatFile(CurOpMode = %d)\n", CurOpMode)); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { if (apidx > pAd->ApCfg.BssidNum) { DBGPRINT(RT_DEBUG_TRACE, ("<----- WscWriteConfToDatFile (wrong apidx = %d)\n", apidx)); return; } pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl; fileName = AP_PROFILE_PATH; snprintf((PSTRING) WepKeyName, sizeof(WepKeyName), "Key%dStr%d=", pAd->ApCfg.MBSSID[apidx].DefaultKeyId+1, apidx+1); snprintf((PSTRING) WepKeyFormatName, sizeof(WepKeyFormatName), "Key%dType=", pAd->ApCfg.MBSSID[apidx].DefaultKeyId+1); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { pWscControl = &pAd->StaCfg.WscControl; fileName = STA_PROFILE_PATH; snprintf(WepKeyName, sizeof(WepKeyName), "Key%dStr=", pAd->StaCfg.DefaultKeyId+1); snprintf(WepKeyFormatName, sizeof(WepKeyFormatName), "Key%dType=", pAd->StaCfg.DefaultKeyId+1); } #endif /* CONFIG_STA_SUPPORT */ RtmpOSFSInfoChange(&osFSInfo, TRUE); file_r = RtmpOSFileOpen(fileName, O_RDONLY, 0); if (IS_FILE_OPEN_ERR(file_r)) { DBGPRINT(RT_DEBUG_TRACE, ("-->1) %s: Error opening file %s\n", __FUNCTION__, fileName)); return; } else { char tempStr[64] = {0}; while((rv = RtmpOSFileRead(file_r, tempStr, 64)) > 0) { fileLen += rv; } os_alloc_mem(NULL, (UCHAR **)&cfgData, fileLen); if (cfgData == NULL) { RtmpOSFileClose(file_r); DBGPRINT(RT_DEBUG_TRACE, ("CfgData kmalloc fail. (fileLen = %ld)\n", fileLen)); goto out; } NdisZeroMemory(cfgData, fileLen); RtmpOSFileSeek(file_r, 0); rv = RtmpOSFileRead(file_r, (PSTRING)cfgData, fileLen); RtmpOSFileClose(file_r); if (rv != fileLen) { DBGPRINT(RT_DEBUG_TRACE, ("CfgData kmalloc fail, fileLen = %ld\n", fileLen)); goto ReadErr; } } file_w = RtmpOSFileOpen(fileName, O_WRONLY|O_TRUNC, 0); if (IS_FILE_OPEN_ERR(file_w)) { goto WriteFileOpenErr; } else { offset = (PCHAR) rtstrstr((PSTRING) cfgData, "Default\n"); offset += strlen("Default\n"); RtmpOSFileWrite(file_w, (PSTRING)cfgData, (int)(offset-cfgData)); os_alloc_mem(NULL, (UCHAR **)&pTempStr, 512); if (!pTempStr) { DBGPRINT(RT_DEBUG_TRACE, ("pTempStr kmalloc fail. (512)\n")); RtmpOSFileClose(file_w); goto WriteErr; } for (;;) { int i = 0; PSTRING ptr; BOOLEAN bNewFormat = TRUE; NdisZeroMemory(pTempStr, 512); ptr = (PSTRING) offset; while(*ptr && *ptr != '\n') { pTempStr[i++] = *ptr++; } pTempStr[i] = 0x00; if ((size_t)(offset - cfgData) < fileLen) { offset += strlen(pTempStr) + 1; if ((strncmp(pTempStr, "SSID=", strlen("SSID=")) == 0) || strncmp(pTempStr, "SSID1=", strlen("SSID1=")) == 0 || strncmp(pTempStr, "SSID2=", strlen("SSID2=")) == 0 || strncmp(pTempStr, "SSID3=", strlen("SSID3=")) == 0 || strncmp(pTempStr, "SSID4=", strlen("SSID4=")) == 0 ) { if (rtstrstr(pTempStr, "SSID=")) bNewFormat = FALSE; WscWriteSsidToDatFile(pAd, pTempStr, bNewFormat, CurOpMode); } #ifdef CONFIG_STA_SUPPORT else if (strncmp(pTempStr, "NetworkType=", strlen("NetworkType=")) == 0) { NdisZeroMemory(pTempStr, 512); if (pAd->StaCfg.BssType == BSS_ADHOC) snprintf(pTempStr, 512, "NetworkType=Adhoc"); else snprintf(pTempStr, 512, "NetworkType=Infra"); } #endif /* CONFIG_STA_SUPPORT */ else if (strncmp(pTempStr, "AuthMode=", strlen("AuthMode=")) == 0) { NdisZeroMemory(pTempStr, 512); snprintf(pTempStr, 512, "AuthMode="); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { for (index = 0; index < pAd->ApCfg.BssidNum; index++) { if (pAd->ApCfg.MBSSID[index].SsidLen) { if (index == 0) snprintf(pTempStr, 512, "%s%s", pTempStr, RTMPGetRalinkAuthModeStr(pAd->ApCfg.MBSSID[index].AuthMode)); else snprintf(pTempStr, 512, "%s;%s", pTempStr, RTMPGetRalinkAuthModeStr(pAd->ApCfg.MBSSID[index].AuthMode)); } } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { USHORT auth_flag = WscGetAuthType(pAd->StaCfg.AuthMode); snprintf(pTempStr, 512, "%s%s", pTempStr, WscGetAuthTypeStr(auth_flag)); } #endif /* CONFIG_STA_SUPPORT */ } else if (strncmp(pTempStr, "EncrypType=", strlen("EncrypType=")) == 0) { NdisZeroMemory(pTempStr, 512); snprintf(pTempStr, 512, "EncrypType="); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { for (index = 0; index < pAd->ApCfg.BssidNum; index++) { if (index == 0) snprintf(pTempStr, 512, "%s%s", pTempStr, RTMPGetRalinkEncryModeStr(pAd->ApCfg.MBSSID[index].WepStatus)); else snprintf(pTempStr, 512, "%s;%s", pTempStr, RTMPGetRalinkEncryModeStr(pAd->ApCfg.MBSSID[index].WepStatus)); } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) { USHORT encrypt_flag = WscGetEncryType(pAd->StaCfg.WepStatus); snprintf(pTempStr, 512, "%s%s", pTempStr, WscGetEncryTypeStr(encrypt_flag)); } #endif /* CONFIG_STA_SUPPORT */ } else if ((strncmp(pTempStr, "WPAPSK=", strlen("WPAPSK=")) == 0) || (strncmp(pTempStr, "WPAPSK1=", strlen("WPAPSK1=")) == 0) || (strncmp(pTempStr, "WPAPSK2=", strlen("WPAPSK2=")) == 0) || (strncmp(pTempStr, "WPAPSK3=", strlen("WPAPSK3=")) == 0) || (strncmp(pTempStr, "WPAPSK4=", strlen("WPAPSK4=")) == 0)) { bNewFormat = TRUE; if (strstr(pTempStr, "WPAPSK=")) bNewFormat = FALSE; WscWriteWpaPskToDatFile(pAd, pTempStr, bNewFormat); } else if (strncmp(pTempStr, "WscConfMode=", strlen("WscConfMode=")) == 0) { snprintf(pTempStr, 512, "WscConfMode="); #ifdef CONFIG_AP_SUPPORT for (index = 0; index < pAd->ApCfg.BssidNum; index++) { pWscControl = &pAd->ApCfg.MBSSID[index].WscControl; if (index == 0) snprintf(pTempStr, 512, "%s%d", pTempStr, pWscControl->WscConfMode); else snprintf(pTempStr, 512, "%s;%d", pTempStr, pWscControl->WscConfMode); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT snprintf(pTempStr, 512, "%s%d", pTempStr, pWscControl->WscConfMode); #endif /* CONFIG_STA_SUPPORT */ } else if (strncmp(pTempStr, "WscConfStatus=", strlen("WscConfStatus=")) == 0) { snprintf(pTempStr, 512, "WscConfStatus="); #ifdef CONFIG_AP_SUPPORT for (index = 0; index < pAd->ApCfg.BssidNum; index++) { pWscControl = &pAd->ApCfg.MBSSID[index].WscControl; if (index == 0) snprintf(pTempStr, 512, "%s%d", pTempStr, pWscControl->WscConfStatus); else snprintf(pTempStr, 512, "%s;%d", pTempStr, pWscControl->WscConfStatus); } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT snprintf(pTempStr, 512, "%s%d", pTempStr, pWscControl->WscConfStatus); #endif /* CONFIG_STA_SUPPORT */ } else if (strncmp(pTempStr, "DefaultKeyID=", strlen("DefaultKeyID=")) == 0) { NdisZeroMemory(pTempStr, 512); snprintf(pTempStr, 512, "DefaultKeyID="); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { for (index = 0; index < pAd->ApCfg.BssidNum; index++) { if (index == 0) snprintf(pTempStr, 512, "%s%d", pTempStr, pAd->ApCfg.MBSSID[index].DefaultKeyId+1); else snprintf(pTempStr, 512, "%s;%d", pTempStr, pAd->ApCfg.MBSSID[index].DefaultKeyId+1); } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT if (CurOpMode == STA_MODE) snprintf(pTempStr, 512, "%s%d", pTempStr, pAd->StaCfg.DefaultKeyId+1); #endif /* CONFIG_STA_SUPPORT */ } #ifdef CONFIG_AP_SUPPORT else if ((strncmp(pTempStr, WepKeyFormatName, strlen(WepKeyFormatName)) == 0) && (CurOpMode == AP_MODE)) { pCredentail = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0]; if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled) { UCHAR idx = 0, KeyType[4] = {0}; PSTRING ptr2, temp_ptr; ptr2 = rtstrstr(pTempStr, "="); temp_ptr = pTempStr; pTempStr = ptr2+1; KeyType[0] = (UCHAR)(*pTempStr - 0x30); for (idx = 1; idx < 4; idx++) { ptr2 = rtstrstr(pTempStr, ";"); if (ptr2 == NULL) break; pTempStr = ptr2+1; if ((pTempStr != NULL) || (*pTempStr == '0') || (*pTempStr == '1')) KeyType[idx] = (UCHAR)(*pTempStr - 0x30); } pTempStr = temp_ptr; NdisZeroMemory(pTempStr, 512); NdisMoveMemory(pTempStr, WepKeyFormatName, strlen(WepKeyFormatName)); for (idx = 0; idx < pAd->ApCfg.BssidNum; idx++) { if (idx == apidx) snprintf(pTempStr, 512, "%s0", pTempStr); else snprintf(pTempStr, 512, "%s%d", pTempStr, KeyType[idx]); if (apidx < (pAd->ApCfg.BssidNum - 1)) snprintf(pTempStr, 512, "%s;", pTempStr); } } } else if ((strncmp(pTempStr, WepKeyName, strlen(WepKeyName)) == 0) && (CurOpMode == AP_MODE)) { pCredentail = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0]; if (pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled) { NdisZeroMemory(pTempStr, 512); NdisMoveMemory(pTempStr, WepKeyName, strlen(WepKeyName)); tempStrLen = strlen(pTempStr); if (pCredentail->KeyLength) { if ((pCredentail->KeyLength == 5) || (pCredentail->KeyLength == 13)) { int jjj=0; for (jjj=0; jjjKeyLength; jjj++) snprintf(pTempStr, 512, "%s%02x", pTempStr, pCredentail->Key[jjj]); } else if ((pCredentail->KeyLength == 10) || (pCredentail->KeyLength == 26)) { NdisMoveMemory(pTempStr + tempStrLen, pCredentail->Key, pCredentail->KeyLength); } } } } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT else if (rtstrstr(pTempStr, (PSTRING) WepKeyFormatName) && (CurOpMode == STA_MODE)) { pCredentail = &pWscControl->WscProfile.Profile[pWscControl->WscProfile.ApplyProfileIdx]; if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) { NdisZeroMemory(pTempStr, 512); snprintf(pTempStr, 512, "%s0", WepKeyFormatName); /* Hex */ } } else if (rtstrstr(pTempStr, (PSTRING) WepKeyName) && (CurOpMode == STA_MODE)) { pCredentail = &pWscControl->WscProfile.Profile[pWscControl->WscProfile.ApplyProfileIdx]; if (pAd->StaCfg.WepStatus == Ndis802_11WEPEnabled) { NdisZeroMemory(pTempStr, 512); NdisMoveMemory(pTempStr, WepKeyName, strlen(WepKeyName)); tempStrLen = strlen(pTempStr); if (pCredentail->KeyLength) { if ((pCredentail->KeyLength == 5) || (pCredentail->KeyLength == 13)) { int jjj=0; for (jjj=0; jjjKeyLength; jjj++) snprintf(pTempStr, 512, "%s%02x", pTempStr, pCredentail->Key[jjj]); } else if ((pCredentail->KeyLength == 10) || (pCredentail->KeyLength == 26)) { NdisMoveMemory(pTempStr + tempStrLen, pCredentail->Key, pCredentail->KeyLength); } } } } #endif /* CONFIG_STA_SUPPORT */ RtmpOSFileWrite(file_w, pTempStr, strlen(pTempStr)); RtmpOSFileWrite(file_w, "\n", 1); } else { break; } } RtmpOSFileClose(file_w); } WriteErr: if (pTempStr) /* kfree(pTempStr); */ os_free_mem(NULL, pTempStr); ReadErr: WriteFileOpenErr: if (cfgData) /* kfree(cfgData); */ os_free_mem(NULL, cfgData); out: RtmpOSFSInfoChange(&osFSInfo, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscWriteConfToDatFile\n")); return; } #ifdef CONFIG_AP_SUPPORT void WscWriteConfToAR9File( IN PRTMP_ADAPTER pAd, IN UCHAR CurOpMode) { PSTRING fileName = NULL; RTMP_OS_FD file_w; RTMP_OS_FS_INFO osFSInfo; INT offset = 0; INT datoffset = 0; PSTRING pTempStr = 0; PSTRING pDatStr = 0; #ifdef CONFIG_AP_SUPPORT INT index = 0; UCHAR apidx = MAIN_MBSSID; #endif /* CONFIG_AP_SUPPORT */ PWSC_CTRL pWscControl = NULL; PWSC_CREDENTIAL pCredentail = NULL; STRING WepKeyName[MAX_WEPKEYNAME_LEN] = {0}; STRING WepKeyFormatName[MAX_WEPKEYTYPE_LEN] = {0}; INT tempStrLen = 0; STRING item_str[10] = {0}; DBGPRINT(RT_DEBUG_TRACE, ("-----> WscWriteConfToAR9File\n")); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl; fileName = "/var/wps_profile.dat"; snprintf((PSTRING) WepKeyName, sizeof(WepKeyName), "Key%dStr1=", pAd->ApCfg.MBSSID[MAIN_MBSSID].DefaultKeyId+1); snprintf((PSTRING) WepKeyFormatName, sizeof(WepKeyFormatName), "Key%dType=", pAd->ApCfg.MBSSID[MAIN_MBSSID].DefaultKeyId+1); } #endif /* CONFIG_AP_SUPPORT */ RtmpOSFSInfoChange(&osFSInfo, TRUE); file_w = RtmpOSFileOpen(fileName, O_WRONLY|O_CREAT, 0); if (IS_FILE_OPEN_ERR(file_w)) { goto WriteFileOpenErr; } else { os_alloc_mem(NULL, (UCHAR **)&pTempStr, 512); if (!pTempStr) { DBGPRINT(RT_DEBUG_TRACE, ("pTempStr kmalloc fail. (512)\n")); RtmpOSFileClose(file_w); goto WriteErr; } os_alloc_mem(NULL, (UCHAR **)&pDatStr, 4096); if (!pDatStr) { DBGPRINT(RT_DEBUG_TRACE, ("pDatStr kmalloc fail. (4096)\n")); RtmpOSFileClose(file_w); goto WriteErr; } /*for (;;) */ { NdisZeroMemory(pTempStr, 512); NdisZeroMemory(pDatStr, 4096); { { NdisZeroMemory(item_str, 10); for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { snprintf(item_str, sizeof(item_str), "SSID%d", (apidx + 1)); { NdisMoveMemory(pTempStr, item_str, strlen(item_str)); offset = strlen(pTempStr); NdisMoveMemory(pTempStr + offset, "=", 1); offset += 1; NdisMoveMemory(pTempStr + offset, pAd->ApCfg.MBSSID[apidx].Ssid, pAd->ApCfg.MBSSID[apidx].SsidLen); offset += pAd->ApCfg.MBSSID[apidx].SsidLen; NdisMoveMemory(pTempStr + offset, "\n", 1); offset += 1; } NdisZeroMemory(item_str, 10); } } NdisMoveMemory(pDatStr,pTempStr,offset); datoffset += offset; { offset=0; NdisZeroMemory(pTempStr, 512); snprintf(pTempStr, 512, "AuthMode="); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { for (index = 0; index < pAd->ApCfg.BssidNum; index++) { if (pAd->ApCfg.MBSSID[index].SsidLen) { if (index == 0) snprintf(pTempStr, 512, "%s%s", pTempStr, RTMPGetRalinkAuthModeStr(pAd->ApCfg.MBSSID[index].AuthMode)); else snprintf(pTempStr, 512, "%s;%s", pTempStr, RTMPGetRalinkAuthModeStr(pAd->ApCfg.MBSSID[index].AuthMode)); } } snprintf(pTempStr, 512, "%s\n", pTempStr); offset=strlen(pTempStr); NdisMoveMemory(pDatStr+datoffset,pTempStr,offset); datoffset += offset; } #endif /* CONFIG_AP_SUPPORT */ } { offset=0; NdisZeroMemory(pTempStr, 512); snprintf(pTempStr, 512, "EncrypType="); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { for (index = 0; index < pAd->ApCfg.BssidNum; index++) { if (index == 0) snprintf(pTempStr, 512, "%s%s", pTempStr, RTMPGetRalinkEncryModeStr(pAd->ApCfg.MBSSID[index].WepStatus)); else snprintf(pTempStr, 512, "%s;%s", pTempStr, RTMPGetRalinkEncryModeStr(pAd->ApCfg.MBSSID[index].WepStatus)); } snprintf(pTempStr, 512, "%s\n", pTempStr); offset=strlen(pTempStr); NdisMoveMemory(pDatStr+datoffset,pTempStr,offset); datoffset += offset; } #endif /* CONFIG_AP_SUPPORT */ } { offset=0; NdisZeroMemory(pTempStr, 512); NdisZeroMemory(item_str, 10); for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { snprintf(item_str, sizeof(item_str), "WPAPSK%d", (apidx + 1)); /*if (rtstrstr(pTempStr, item_str)) */ { pWscControl = &pAd->ApCfg.MBSSID[apidx].WscControl; NdisMoveMemory(pTempStr, item_str, strlen(item_str)); offset = strlen(pTempStr); NdisMoveMemory(pTempStr + offset, "=", 1); offset += 1; NdisMoveMemory(pTempStr + offset, pWscControl->WpaPsk, pWscControl->WpaPskLen); offset += pWscControl->WpaPskLen; NdisMoveMemory(pTempStr + offset, "\n", 1); offset += 1; } NdisZeroMemory(item_str, 10); } NdisMoveMemory(pDatStr+datoffset,pTempStr,offset); datoffset += offset; } { offset=0; NdisZeroMemory(pTempStr, 512); snprintf(pTempStr, 512, "WscConfMode="); #ifdef CONFIG_AP_SUPPORT for (index = 0; index < pAd->ApCfg.BssidNum; index++) { pWscControl = &pAd->ApCfg.MBSSID[index].WscControl; if (index == 0) snprintf(pTempStr, 512, "%s%d", pTempStr, pWscControl->WscConfMode); else snprintf(pTempStr, 512, "%s;%d", pTempStr, pWscControl->WscConfMode); } snprintf(pTempStr, 512, "%s\n", pTempStr); offset=strlen(pTempStr); NdisMoveMemory(pDatStr+datoffset,pTempStr,offset); datoffset += offset; #endif /* CONFIG_AP_SUPPORT */ } { offset=0; NdisZeroMemory(pTempStr, 512); snprintf(pTempStr, 512, "WscConfStatus="); #ifdef CONFIG_AP_SUPPORT for (index = 0; index < pAd->ApCfg.BssidNum; index++) { pWscControl = &pAd->ApCfg.MBSSID[index].WscControl; if (index == 0) snprintf(pTempStr, 512, "%s%d", pTempStr, pWscControl->WscConfStatus); else snprintf(pTempStr, 512, "%s;%d", pTempStr, pWscControl->WscConfStatus); } snprintf(pTempStr, 512, "%s\n", pTempStr); offset=strlen(pTempStr); NdisMoveMemory(pDatStr+datoffset,pTempStr,offset); datoffset += offset; #endif /* CONFIG_AP_SUPPORT */ } { offset=0; NdisZeroMemory(pTempStr, 512); snprintf(pTempStr, 512, "DefaultKeyID="); #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { for (index = 0; index < pAd->ApCfg.BssidNum; index++) { pWscControl = &pAd->ApCfg.MBSSID[index].WscControl; if (index == 0) snprintf(pTempStr, 512, "%s%d", pTempStr, pAd->ApCfg.MBSSID[apidx].DefaultKeyId+1); else snprintf(pTempStr, 512, "%s;%d", pTempStr, pAd->ApCfg.MBSSID[apidx].DefaultKeyId+1); } snprintf(pTempStr, 512, "%s\n", pTempStr); offset=strlen(pTempStr); NdisMoveMemory(pDatStr+datoffset,pTempStr,offset); datoffset += offset; } #endif /* CONFIG_AP_SUPPORT */ } #ifdef CONFIG_AP_SUPPORT if (CurOpMode == AP_MODE) { for (index = 1; index <= 4; index++) { snprintf(WepKeyFormatName, sizeof(WepKeyFormatName), "Key%dType=", index); /*if (rtstrstr(pTempStr, WepKeyFormatName)) */ { NdisZeroMemory(pTempStr, 512); offset=0; NdisMoveMemory(pTempStr, WepKeyFormatName, strlen(WepKeyFormatName)); for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { if (pAd->ApCfg.MBSSID[MAIN_MBSSID].WepStatus == Ndis802_11WEPEnabled) { pCredentail = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0]; if ((pCredentail->KeyLength == 5) || (pCredentail->KeyLength == 13)) snprintf(pTempStr, 512, "%s1", pTempStr); /* ASCII */ else snprintf(pTempStr, 512, "%s0", pTempStr); /* Hex */ } if (apidx < (pAd->ApCfg.BssidNum - 1)) snprintf(pTempStr, 512, "%s;", pTempStr); } snprintf(pTempStr, 512, "%s\n", pTempStr); offset=strlen(pTempStr); NdisMoveMemory(pDatStr+datoffset,pTempStr,offset); datoffset += offset; } snprintf(WepKeyName, sizeof(WepKeyName), "Key%dStr=", index); /*if (rtstrstr(pTempStr, WepKeyName)) */ { NdisZeroMemory(pTempStr, 512); offset=0; NdisMoveMemory(pTempStr, WepKeyName, strlen(WepKeyName)); tempStrLen = strlen(pTempStr); for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { pCredentail = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0]; if (pCredentail->KeyLength) { NdisMoveMemory(pTempStr + tempStrLen, pCredentail->Key, pCredentail->KeyLength); tempStrLen = strlen(pTempStr); } if (apidx < (pAd->ApCfg.BssidNum - 1)) NdisMoveMemory(pTempStr + tempStrLen, ";", 1); tempStrLen += 1; } snprintf(pTempStr, 512, "%s\n", pTempStr); offset=strlen(pTempStr); NdisMoveMemory(pDatStr+datoffset,pTempStr,offset); datoffset += offset; } for (apidx = 0; apidx < pAd->ApCfg.BssidNum; apidx++) { snprintf(WepKeyName, sizeof(WepKeyName), "Key%dStr%d=", index, (apidx + 1)); if ((pAd->ApCfg.MBSSID[apidx].WepStatus == Ndis802_11WEPEnabled)) { NdisZeroMemory(pTempStr, 512); NdisMoveMemory(pTempStr, WepKeyName, strlen(WepKeyName)); tempStrLen = strlen(pTempStr); pCredentail = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0]; NdisMoveMemory(pTempStr + tempStrLen, pCredentail->Key, pCredentail->KeyLength); NdisMoveMemory(pTempStr + tempStrLen+pCredentail->KeyLength, "\n", 1); } offset=tempStrLen+pCredentail->KeyLength+1; NdisMoveMemory(pDatStr+datoffset,pTempStr,offset); datoffset += offset; } } } #endif /* CONFIG_AP_SUPPORT */ RtmpOSFileWrite(file_w, pDatStr, datoffset); /*RtmpOSFileWrite(file_w, "\n", 1); */ } } RtmpOSFileClose(file_w); } WriteErr: if (pTempStr) /* kfree(pTempStr); */ os_free_mem(NULL, pTempStr); if (pDatStr) /* kfree(pDatStr); */ os_free_mem(NULL, pDatStr); WriteFileOpenErr: RtmpOSFSInfoChange(&osFSInfo, FALSE); DBGPRINT(RT_DEBUG_TRACE, ("<----- WscWriteConfToAR9File\n")); return; } #endif/*CONFIG_AP_SUPPORT*/ static INT wsc_write_dat_file_thread ( IN ULONG Context) { RTMP_OS_TASK *pTask; RTMP_ADAPTER *pAd; int Status = 0; pTask = (RTMP_OS_TASK *)Context; pAd = (PRTMP_ADAPTER)RTMP_OS_TASK_DATA_GET(pTask); if (pAd == NULL) return 0; RtmpOSTaskCustomize(pTask); while (pTask && !RTMP_OS_TASK_IS_KILLED(pTask)) { RTMPusecDelay(2000); if (RtmpOSTaskWait(pAd, pTask, &Status) == FALSE) { RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS); break; } if (Status != 0) break; #ifdef RTMP_MAC_USB /* device had been closed */ if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_NIC_NOT_EXIST)) break; #endif /* RTMP_MAC_USB */ if (pAd->pWscElme && (pAd->pWscElme->MsgLen != 0)) { MLME_QUEUE_ELEM *pElme; os_alloc_mem(pAd, (UCHAR **)&pElme, sizeof(MLME_QUEUE_ELEM)); if (pElme) { NdisZeroMemory(pElme, sizeof(MLME_QUEUE_ELEM)); RTMP_SEM_LOCK(&pAd->WscElmeLock); NdisMoveMemory(pElme, pAd->pWscElme, sizeof(MLME_QUEUE_ELEM)); pAd->pWscElme->MsgLen = 0; NdisZeroMemory(pAd->pWscElme->Msg, MGMT_DMA_BUFFER_SIZE); RTMP_SEM_UNLOCK(&pAd->WscElmeLock); WpsSmProcess(pAd, pElme); os_free_mem(NULL, pElme); } } if (pAd->WriteWscCfgToDatFile != 0xFF) { UCHAR CurOpMode = AP_MODE; #ifdef CONFIG_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) CurOpMode = AP_MODE; #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) CurOpMode = STA_MODE; if (pAd->WriteWscCfgToDatFile != BSS0) CurOpMode = AP_MODE; #endif /* CONFIG_STA_SUPPORT */ WscWriteConfToDatFile(pAd, CurOpMode); #ifdef CONFIG_AP_SUPPORT #ifdef INF_AR9 #ifdef AR9_MAPI_SUPPORT WscWriteConfToAR9File(pAd, CurOpMode); #endif /*AR9_MAPI_SUPPORT*/ #endif /* INF_AR9 */ #endif/*CONFIG_AP_SUPPORT*/ pAd->WriteWscCfgToDatFile = 0xFF; } } if (pTask) RtmpOSTaskNotifyToExit(pTask); return 0; } /* * This kernel thread init in the probe fucntion, so we should kill it when do remove module. */ BOOLEAN WscThreadExit(RTMP_ADAPTER *pAd) { INT ret; /* This kernel thread init in the probe fucntion, so kill it when do remove module. */ ret = RtmpOSTaskKill(&pAd->wscTask); if (ret == NDIS_STATUS_FAILURE) { DBGPRINT(RT_DEBUG_ERROR, ("kill wsc task failed!\n")); } if (pAd->pHmacData) { os_free_mem(NULL, pAd->pHmacData); pAd->pHmacData = NULL; } if (pAd->pWscElme) { os_free_mem(NULL, pAd->pWscElme); pAd->pWscElme = NULL; } NdisFreeSpinLock(&pAd->WscElmeLock); #ifdef CONFIG_AP_SUPPORT if ((pAd->OpMode == OPMODE_AP) #ifdef P2P_SUPPORT /* P2P will use ApCfg.MBSSID and ApCfg.ApCliTab also. */ || TRUE #endif /* P2P_SUPPORT */ ) { INT ap_idx; UCHAR MaxBssidNum = MAX_MBSSID_NUM(pAd); for (ap_idx = 0; ap_idx < MaxBssidNum; ap_idx++) { PWSC_CTRL pWpsCtrl = &pAd->ApCfg.MBSSID[ap_idx].WscControl; WscStop(pAd, FALSE, pWpsCtrl); pWpsCtrl->WscRxBufLen = 0; if (pWpsCtrl->pWscRxBuf) { os_free_mem(pAd, pWpsCtrl->pWscRxBuf); pWpsCtrl->pWscRxBuf = NULL; } pWpsCtrl->WscTxBufLen = 0; if (pWpsCtrl->pWscTxBuf) { os_free_mem(pAd, pWpsCtrl->pWscTxBuf); pWpsCtrl->pWscTxBuf = NULL; } #ifdef WSC_V2_SUPPORT if (pWpsCtrl->WscV2Info.ExtraTlv.pTlvData) { os_free_mem(NULL, pWpsCtrl->WscV2Info.ExtraTlv.pTlvData); pWpsCtrl->WscV2Info.ExtraTlv.pTlvData = NULL; } #endif // WSC_V2_SUPPORT // WscClearPeerList(&pWpsCtrl->WscPeerList); NdisFreeSpinLock(&pWpsCtrl->WscPeerListSemLock); } #ifdef APCLI_SUPPORT { INT index; WscStop(pAd, TRUE, &pAd->ApCfg.ApCliTab[BSS0].WscControl); for(index = 0; index < MAX_APCLI_NUM; index++) { PWSC_CTRL pWpsCtrl = &pAd->ApCfg.ApCliTab[index].WscControl; pWpsCtrl->WscTxBufLen = 0; if (pWpsCtrl->pWscTxBuf) os_free_mem(pAd, pWpsCtrl->pWscTxBuf); pWpsCtrl->WscRxBufLen = 0; if (pWpsCtrl->pWscRxBuf) os_free_mem(pAd, pWpsCtrl->pWscRxBuf); WscClearPeerList(&pWpsCtrl->WscPeerList); NdisFreeSpinLock(&pWpsCtrl->WscPeerListSemLock); } } #endif // APCLI_SUPPORT // } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { WscStop(pAd, #ifdef CONFIG_AP_SUPPORT FALSE, #endif // CONFIG_AP_SUPPORT // &pAd->StaCfg.WscControl); pAd->StaCfg.WscControl.WscRxBufLen = 0; if (pAd->StaCfg.WscControl.pWscRxBuf) { os_free_mem(pAd, pAd->StaCfg.WscControl.pWscRxBuf); pAd->StaCfg.WscControl.pWscRxBuf = NULL; } pAd->StaCfg.WscControl.WscTxBufLen = 0; if (pAd->StaCfg.WscControl.pWscTxBuf) { os_free_mem(pAd, pAd->StaCfg.WscControl.pWscTxBuf); pAd->StaCfg.WscControl.pWscTxBuf = NULL; } WscClearPeerList(&pAd->StaCfg.WscControl.WscPeerList); NdisFreeSpinLock(&pAd->StaCfg.WscControl.WscPeerListSemLock); #ifdef IWSC_SUPPORT WscClearPeerList(&pAd->StaCfg.WscControl.WscConfiguredPeerList); NdisFreeSpinLock(&pAd->StaCfg.WscControl.WscConfiguredPeerListSemLock); #endif /* IWSC_SUPPORT */ } #endif /* CONFIG_STA_SUPPORT */ /* WSC hardware push button function 0811 */ WSC_HDR_BTN_Stop(pAd); return TRUE; } /* * This kernel thread init in the probe function. */ NDIS_STATUS WscThreadInit(RTMP_ADAPTER *pAd) { NDIS_STATUS status = NDIS_STATUS_FAILURE; RTMP_OS_TASK *pTask; DBGPRINT(RT_DEBUG_TRACE, ("-->WscThreadInit()\n")); pTask = &pAd->wscTask; RTMP_OS_TASK_INIT(pTask, "RtmpWscTask", pAd); status = RtmpOSTaskAttach(pTask, wsc_write_dat_file_thread, (ULONG)&pAd->wscTask); if (status == NDIS_STATUS_SUCCESS) { os_alloc_mem(NULL, &pAd->pHmacData, sizeof(CHAR)*(2048)); if (pAd->pHmacData == NULL) { DBGPRINT(RT_DEBUG_ERROR, ("Wsc HmacData memory alloc failed!\n")); status = FALSE; } NdisAllocateSpinLock(pAd, &pAd->WscElmeLock); os_alloc_mem(NULL, (UCHAR **)&pAd->pWscElme, sizeof(MLME_QUEUE_ELEM)); } DBGPRINT(RT_DEBUG_TRACE, ("<--WscThreadInit(), status=%d!\n", status)); return status; } /* WSC hardware push button function 0811 */ /* ======================================================================== Routine Description: Initialize the PUSH PUTTION Check Module. Arguments: ad_p - WLAN control block pointer Return Value: None Note: ======================================================================== */ VOID WSC_HDR_BTN_Init( IN PRTMP_ADAPTER pAd) { pAd->CommonCfg.WscHdrPshBtnCheckCount = 0; } /* End of WSC_HDR_BTN_Init */ /* ======================================================================== Routine Description: Stop the PUSH PUTTION Check Module. Arguments: ad_p - WLAN control block pointer Return Value: None Note: ======================================================================== */ VOID WSC_HDR_BTN_Stop( IN PRTMP_ADAPTER pAd) { pAd->CommonCfg.WscHdrPshBtnCheckCount = 0; } /* End of WSC_HDR_BTN_Stop */ /* ======================================================================== Routine Description: Start the PUSH PUTTION Check thread. Arguments: *Context - WLAN control block pointer Return Value: 0 - terminate the thread successfully Note: ======================================================================== */ #if 0 //def WSC_AP_SUPPORT extern INT Set_AP_WscMode_Proc( IN PRTMP_ADAPTER pAd, IN PUCHAR arg); extern INT Set_AP_WscGetConf_Proc( IN PRTMP_ADAPTER pAd, IN PUCHAR arg); #endif /* CONFIG_AP_SUPPORT */ /*#ifdef CONFIG_STA_SUPPORT */ VOID WSC_HDR_BTN_CheckHandler( IN PRTMP_ADAPTER pAd) { POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie; BOOLEAN flg_pressed; #ifdef MT7601 if (IS_MT7601(pAd)) { MT7601_WSC_HDR_BTN_MR_PRESS_FLG_GET(pAd, flg_pressed); } else #endif /* MT7601 */ WSC_HDR_BTN_MR_PRESS_FLG_GET(pAd, flg_pressed); if (flg_pressed) { /* the button is pressed */ if (pAd->CommonCfg.WscHdrPshBtnCheckCount == WSC_HDR_BTN_CONT_TIMES) { /* we only handle once until the button is released */ pAd->CommonCfg.WscHdrPshBtnCheckCount = 0; /* execute WSC PBC function */ DBGPRINT(RT_DEBUG_ERROR, ("wsc> execute WSC PBC...\n")); #if 0 //def WSC_AP_SUPPORT IF_DEV_CONFIG_OPMODE_ON_AP(pAd) { pObj->ioctl_if = 0; Set_AP_WscMode_Proc(pAd, (PUCHAR)"2"); /* 2: PBC */ Set_AP_WscGetConf_Proc(pAd, (PUCHAR)"1"); /* 1: Trigger */ } #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT IF_DEV_CONFIG_OPMODE_ON_STA(pAd) { pObj->ioctl_if = 0; Set_WscConfMode_Proc(pAd, (PUCHAR)"1"); /* 1: */ Set_WscMode_Proc(pAd, (PUCHAR)"2"); /* 2: PBC */ Set_WscGetConf_Proc(pAd, (PUCHAR)"1"); /* 1: Trigger */ } #endif /* CONFIG_STA_SUPPORT */ return; } pAd->CommonCfg.WscHdrPshBtnCheckCount ++; } else { /* the button is released */ pAd->CommonCfg.WscHdrPshBtnCheckCount = 0; } } #ifdef WSC_LED_SUPPORT /* */ /* Support WPS LED mode (mode 7, mode 8 and mode 9). */ /* Ref: User Feedback (page 80, WPS specification 1.0) */ /* */ BOOLEAN WscSupportWPSLEDMode( IN PRTMP_ADAPTER pAd) { if ((LED_MODE(pAd) == WPS_LED_MODE_7) || (LED_MODE(pAd) == WPS_LED_MODE_8) || (LED_MODE(pAd) == WPS_LED_MODE_9) || (LED_MODE(pAd) == WPS_LED_MODE_11) || (LED_MODE(pAd) == WPS_LED_MODE_12) #ifdef CONFIG_WIFI_LED_SUPPORT ||(LED_MODE(pAd) == WPS_LED_MODE_SHARE) #endif /* CONFIG_WIFI_LED_SUPPORT */ ) { DBGPRINT(RT_DEBUG_TRACE, ("%s: Support WPS LED mode (The WPS LED mode = %d).\n", __FUNCTION__, LED_MODE(pAd))); return TRUE; /* Support WPS LED mode. */ } else { DBGPRINT(RT_DEBUG_TRACE, ("%s: Not support WPS LED mode (The WPS LED mode = %d).\n", __FUNCTION__, LED_MODE(pAd))); return FALSE; /* Not support WPS LED mode. */ } } BOOLEAN WscSupportWPSLEDMode10( IN PRTMP_ADAPTER pAd) { if ((LED_MODE(pAd) == WPS_LED_MODE_10)){ DBGPRINT(RT_DEBUG_TRACE, ("%s: Support WPS LED mode (The WPS LED mode = %d).\n", __FUNCTION__, LED_MODE(pAd))); return TRUE; /*Support WPS LED mode 10. */ } else { DBGPRINT(RT_DEBUG_TRACE, ("%s: Not support WPS LED mode (The WPS LED mode = %d).\n", __FUNCTION__, LED_MODE(pAd))); return FALSE; /* Not support WPS LED mode 10. */ } } /* */ /* Whether the WPS AP has security setting or not. */ /* Note that this function is valid only after the WPS handshaking. */ /* */ BOOLEAN WscAPHasSecuritySetting( IN PRTMP_ADAPTER pAdapter, IN PWSC_CTRL pWscControl) { BOOLEAN bAPHasSecuritySetting = FALSE; UCHAR currentIdx = MAIN_MBSSID; #ifdef CONFIG_AP_SUPPORT currentIdx = (pWscControl->EntryIfIdx & 0x0F); #endif /* CONFIG_AP_SUPPORT */ #ifdef CONFIG_STA_SUPPORT currentIdx = pWscControl->WscProfile.ApplyProfileIdx; #endif /* CONFIG_STA_SUPPORT */ switch (pWscControl->WscProfile.Profile[currentIdx].EncrType) { case WSC_ENCRTYPE_NONE: { bAPHasSecuritySetting = FALSE; break; } case WSC_ENCRTYPE_WEP: case WSC_ENCRTYPE_TKIP: case (WSC_ENCRTYPE_TKIP | WSC_ENCRTYPE_AES): case WSC_ENCRTYPE_AES: { bAPHasSecuritySetting = TRUE; break; } default: { DBGPRINT(RT_DEBUG_TRACE, ("%s: Incorrect encryption types (%d)\n", __FUNCTION__, pWscControl->WscProfile.Profile[currentIdx].EncrType)); ASSERT(FALSE); break; } } DBGPRINT(RT_DEBUG_TRACE, ("%s: WSC Entryption Type = %d\n", __FUNCTION__, pWscControl->WscProfile.Profile[currentIdx].EncrType)); return bAPHasSecuritySetting; } /* */ /* After the NIC connects with a WPS AP or not, */ /* the WscLEDTimer timer controls the LED behavior according to LED mode. */ /* */ VOID WscLEDTimer( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext; PRTMP_ADAPTER pAd = (PRTMP_ADAPTER)pWscControl->pAd; UCHAR WPSLEDStatus = 0; /* WPS LED mode 7, 8, 11 and 12. */ if ((LED_MODE(pAd) == WPS_LED_MODE_7) || (LED_MODE(pAd) == WPS_LED_MODE_8) || (LED_MODE(pAd) == WPS_LED_MODE_11) || (LED_MODE(pAd) == WPS_LED_MODE_12)) { WPSLEDStatus = LED_WPS_TURN_LED_OFF; DBGPRINT(RT_DEBUG_TRACE, ("%s: Turn off the WPS successful LED pattern.\n", __FUNCTION__)); } else if ((LED_MODE(pAd) == WPS_LED_MODE_9) /* WPS LED mode 9. */ #ifdef CONFIG_WIFI_LED_SUPPORT || (LED_MODE(pAd) == WPS_LED_MODE_SHARE) #endif /* CONFIG_WIFI_LED_SUPPORT */ ) { switch (pWscControl->WscLEDMode) /* Last WPS LED state. */ { /* Turn off the blue LED after 300 seconds. */ case LED_WPS_SUCCESS: WPSLEDStatus = LED_WPS_TURN_LED_OFF; /* Turn on/off the WPS success LED according to AP's encryption algorithm after one second. */ RTMPSetTimer(&pWscControl->WscLEDTimer, WSC_WPS_TURN_OFF_LED_TIMEOUT); pWscControl->WscLEDTimerRunning = TRUE; DBGPRINT(RT_DEBUG_TRACE, ("%s: LED_WPS_SUCCESS => LED_WPS_TURN_LED_OFF\n", __FUNCTION__)); break; /* After turn off the blue LED for one second. */ /* AP uses an encryption algorithm: */ /* a) YES: Turn on the blue LED. */ /* b) NO: Turn off the blue LED. */ case LED_WPS_TURN_LED_OFF: if ((pWscControl->WscState == WSC_STATE_OFF) && (pWscControl->WscStatus == STATUS_WSC_CONFIGURED)) { if (WscAPHasSecuritySetting(pAd, pWscControl) == TRUE) /* The NIC connects with an AP using an encryption algorithm. */ { /* Turn WPS success LED. */ WPSLEDStatus = LED_WPS_TURN_ON_BLUE_LED; DBGPRINT(RT_DEBUG_TRACE, ("%s: LED_WPS_TURN_LED_OFF => LED_WPS_TURN_ON_BLUE_LED\n", __FUNCTION__)); } else /* The NIC connects with an AP using OPEN-NONE. */ { /* Turn off the WPS LED. */ WPSLEDStatus = LED_WPS_TURN_LED_OFF; DBGPRINT(RT_DEBUG_TRACE, ("%s: LED_WPS_TURN_LED_OFF => LED_WPS_TURN_LED_OFF\n", __FUNCTION__)); } } break; /* Turn off the amber LED after 15 seconds. */ case LED_WPS_ERROR: WPSLEDStatus = LED_WPS_TURN_LED_OFF; /* Turn off the WPS LED. */ DBGPRINT(RT_DEBUG_TRACE, ("%s: LED_WPS_ERROR/LED_WPS_SESSION_OVERLAP_DETECTED => LED_WPS_TURN_LED_OFF\n", __FUNCTION__)); break; /* Turn off the amber LED after ~3 seconds. */ case LED_WPS_SESSION_OVERLAP_DETECTED: WPSLEDStatus = LED_WPS_TURN_LED_OFF; /* Turn off the WPS LED. */ DBGPRINT(RT_DEBUG_TRACE, ("%s: LED_WPS_SESSION_OVERLAP_DETECTED => LED_WPS_TURN_LED_OFF\n", __FUNCTION__)); break; default: /* do nothing. */ break; } if (WPSLEDStatus) RTMPSetLED(pAd, WPSLEDStatus); } else { /* do nothing. */ } } VOID WscSkipTurnOffLEDTimer( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext; /* Allow the NIC to turn off the WPS LED again. */ pWscControl->bSkipWPSTurnOffLED = FALSE; DBGPRINT(RT_DEBUG_TRACE, ("%s: Allow the NIC to turn off the WPS LED again.\n", __FUNCTION__)); } #endif /* WSC_LED_SUPPORT */ #ifdef CONFIG_AP_SUPPORT VOID WscUpdatePortCfgTimeout( IN PVOID SystemSpecific1, IN PVOID FunctionContext, IN PVOID SystemSpecific2, IN PVOID SystemSpecific3) { PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext; PRTMP_ADAPTER pAd = NULL; BOOLEAN /* bRestart = TRUE,*/ bEnrollee = TRUE; PWSC_CREDENTIAL pCredential = NULL; PMULTISSID_STRUCT pMbss = NULL; if (pWscControl == NULL) return; pCredential = (PWSC_CREDENTIAL) &pWscControl->WscProfile.Profile[0]; pAd = (PRTMP_ADAPTER)pWscControl->pAd; if (pAd == NULL) return; pMbss = &pAd->ApCfg.MBSSID[pWscControl->EntryIfIdx & 0x0F]; if (WscGetAuthMode(pCredential->AuthType) == pMbss->AuthMode && WscGetWepStatus(pCredential->EncrType) == pMbss->WepStatus && NdisEqualMemory(pMbss->Ssid, pCredential->SSID.Ssid, pMbss->SsidLen) && NdisEqualMemory(pWscControl->WpaPsk, pCredential->Key, pCredential->KeyLength)) { return; } if (pWscControl->WscProfile.ApplyProfileIdx & 0x8000) bEnrollee = FALSE; WscWriteConfToPortCfg(pAd, pWscControl, &pWscControl->WscProfile.Profile[0], bEnrollee); pWscControl->WscProfile.ApplyProfileIdx &= 0x7FFF; #ifdef P2P_SUPPORT if (pWscControl->EntryIfIdx & MIN_NET_DEVICE_FOR_P2P_GO) { P2P_GoStop(pAd); P2P_GoStartUp(pAd, MAIN_MBSSID); } else #endif /* P2P_SUPPORT */ { pAd->WriteWscCfgToDatFile = (pWscControl->EntryIfIdx & 0x0F); APStop(pAd); APStartUp(pAd); } /*#ifdef KTHREAD_SUPPORT */ /* WAKE_UP(&(pAd->wscTask)); */ /*#else */ /* RTMP_SEM_EVENT_UP(&(pAd->wscTask.taskSema)); */ /*#endif */ RtmpOsTaskWakeUp(&(pAd->wscTask)); return; } #endif /* CONFIG_AP_SUPPORT */ VOID WscCheckPeerDPID( IN PRTMP_ADAPTER pAd, IN PFRAME_802_11 Fr, IN PUCHAR eid_data, IN INT eid_len) { WSC_IE *pWscIE; PUCHAR pData = NULL; INT Len = 0; USHORT DevicePasswordID; PWSC_CTRL pWscCtrl = NULL; pData = eid_data + 4; Len = eid_len - 4; while (Len > 0) { WSC_IE WscIE; NdisMoveMemory(&WscIE, pData, sizeof(WSC_IE)); /* Check for WSC IEs*/ pWscIE = &WscIE; /* Check for device password ID, PBC = 0x0004*/ if (be2cpu16(pWscIE->Type) == WSC_ID_DEVICE_PWD_ID) { /* Found device password ID*/ NdisMoveMemory(&DevicePasswordID, pData + 4, sizeof(DevicePasswordID)); DevicePasswordID = be2cpu16(DevicePasswordID); DBGPRINT(RT_DEBUG_INFO, ("%s : DevicePasswordID = 0x%04x\n", __FUNCTION__, DevicePasswordID)); if (DevicePasswordID == DEV_PASS_ID_PBC) /* Check for PBC value*/ { WscPBC_DPID_FromSTA(pAd, Fr->Hdr.Addr2); hex_dump("PBC STA:", Fr->Hdr.Addr2, MAC_ADDR_LEN); DBGPRINT(RT_DEBUG_TRACE, ("\n")); } else if (DevicePasswordID == DEV_PASS_ID_PIN) { #ifdef CONFIG_AP_SUPPORT if ((pAd->OpMode == OPMODE_AP) #ifdef P2P_SUPPORT || P2P_GO_ON(pAd) #endif /* P2P_SUPPORT */ ) { UCHAR ap_idx = 0; for (ap_idx = 0; ap_idx < pAd->ApCfg.BssidNum; ap_idx++) { if (NdisEqualMemory(Fr->Hdr.Addr1, pAd->ApCfg.MBSSID[ap_idx].Bssid, MAC_ADDR_LEN)) break; } if (ap_idx >= pAd->ApCfg.BssidNum) { break; } pWscCtrl = &pAd->ApCfg.MBSSID[ap_idx].WscControl; } #endif /* CONFIG_AP_SUPPORT */ /* WSC 2.0 STA will send probe request with WPS IE anyway. Do NOT add this STA to WscPeerList after AP is triggered to do PBC. */ if (pWscCtrl && (!pWscCtrl->bWscTrigger || (pWscCtrl->WscMode != WSC_PBC_MODE))) { RTMP_SEM_LOCK(&pWscCtrl->WscPeerListSemLock); WscInsertPeerEntryByMAC(&pWscCtrl->WscPeerList, Fr->Hdr.Addr2); RTMP_SEM_UNLOCK(&pWscCtrl->WscPeerListSemLock); } } #ifdef IWSC_SUPPORT else if (DevicePasswordID == DEV_PASS_ID_SMPBC) { IWSC_AddSmpbcEnrollee(pAd, Fr->Hdr.Addr2); } #endif /* IWSC_SUPPORT */ break; } #ifdef IWSC_SUPPORT if (pAd->StaCfg.BssType == BSS_ADHOC) { pWscCtrl = &pAd->StaCfg.WscControl; if ((be2cpu16(pWscIE->Type) == WSC_ID_CONFIG_METHODS) && (pWscCtrl->WscConfMode == WSC_REGISTRAR) && (pWscCtrl->bWscTrigger == TRUE)) { USHORT PeerConfigMethod = 0; PWSC_PEER_ENTRY pWscPeerEntry = NULL; RTMP_SEM_LOCK(&pWscCtrl->WscConfiguredPeerListSemLock); pWscPeerEntry = WscFindPeerEntry(&pWscCtrl->WscConfiguredPeerList, Fr->Hdr.Addr2); if (pWscPeerEntry == NULL) { NdisMoveMemory(&PeerConfigMethod, pData + 4, sizeof(PeerConfigMethod)); PeerConfigMethod = be2cpu16(PeerConfigMethod); if (pWscCtrl->WscMode == WSC_PIN_MODE) { NdisMoveMemory(pWscCtrl->WscPeerMAC, Fr->Hdr.Addr2, MAC_ADDR_LEN); NdisMoveMemory(pWscCtrl->EntryAddr, Fr->Hdr.Addr2, MAC_ADDR_LEN); } MlmeEnqueue(pAd, IWSC_STATE_MACHINE, IWSC_MT2_PEER_PROBE_REQ, sizeof(USHORT), &PeerConfigMethod, 0); RTMP_MLME_HANDLER(pAd); DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity : Add this peer: %02x:%02x:%02x:%02x:%02x:%02x\n", PRINT_MAC(Fr->Hdr.Addr2))); } RTMP_SEM_UNLOCK(&pWscCtrl->WscConfiguredPeerListSemLock); DBGPRINT(RT_DEBUG_TRACE, ("PeerProbeReqSanity : PeerConfigMethod = 0x%04x\n", PeerConfigMethod)); } } #endif /* IWSC_SUPPORT */ /* 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(pWscIE->Length) + 4); Len -= (be2cpu16(pWscIE->Length) + 4); } } VOID WscClearPeerList( IN PLIST_HEADER pWscEnList) { PLIST_ENTRY pEntry = NULL; pEntry = pWscEnList->pHead; while (pEntry != NULL) { removeHeadList(pWscEnList); os_free_mem(NULL, pEntry); pEntry = pWscEnList->pHead; } return; } PWSC_PEER_ENTRY WscFindPeerEntry( PLIST_HEADER pWscEnList, IN PUCHAR pMacAddr) { PWSC_PEER_ENTRY pPeerEntry = NULL; PLIST_ENTRY pListEntry = NULL; pListEntry = pWscEnList->pHead; pPeerEntry = (PWSC_PEER_ENTRY)pListEntry; while (pPeerEntry != NULL) { if (NdisEqualMemory(pPeerEntry->mac_addr, pMacAddr, MAC_ADDR_LEN)) return pPeerEntry; pListEntry = pListEntry->pNext; pPeerEntry = (PWSC_PEER_ENTRY)pListEntry; } return NULL; } VOID WscInsertPeerEntryByMAC( PLIST_HEADER pWscEnList, IN PUCHAR pMacAddr) { PWSC_PEER_ENTRY pWscPeer = NULL; pWscPeer = WscFindPeerEntry(pWscEnList, pMacAddr); if (pWscPeer) { NdisGetSystemUpTime(&pWscPeer->receive_time); } else { os_alloc_mem(NULL, (UCHAR **)&pWscPeer, sizeof(WSC_PEER_ENTRY)); if (pWscPeer) { NdisZeroMemory(pWscPeer, sizeof(WSC_PEER_ENTRY)); pWscPeer->pNext = NULL; NdisMoveMemory(pWscPeer->mac_addr, pMacAddr, MAC_ADDR_LEN); NdisGetSystemUpTime(&pWscPeer->receive_time); insertTailList(pWscEnList, (PLIST_ENTRY)pWscPeer); } ASSERT(pWscPeer != NULL); } } #ifdef CONFIG_AP_SUPPORT INT WscApShowPeerList( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { UCHAR ApIdx = 0; PWSC_CTRL pWscControl = NULL; PWSC_PEER_ENTRY pPeerEntry = NULL; PLIST_ENTRY pListEntry = NULL; PLIST_HEADER pWscEnList = NULL; for (ApIdx = 0; ApIdx < pAd->ApCfg.BssidNum; ApIdx++) { pWscControl = &pAd->ApCfg.MBSSID[ApIdx].WscControl; pWscEnList = &pWscControl->WscPeerList; if (pWscEnList->size != 0) { WscMaintainPeerList(pAd, pWscControl); RTMP_SEM_LOCK(&pWscControl->WscPeerListSemLock); pListEntry = pWscEnList->pHead; pPeerEntry = (PWSC_PEER_ENTRY)pListEntry; while (pPeerEntry != NULL) { printk("MAC:%02x:%02x:%02x:%02x:%02x:%02x\tReveive Time:%lu\n", pPeerEntry->mac_addr[0], pPeerEntry->mac_addr[1], pPeerEntry->mac_addr[2], pPeerEntry->mac_addr[3], pPeerEntry->mac_addr[4], pPeerEntry->mac_addr[5], pPeerEntry->receive_time); pListEntry = pListEntry->pNext; pPeerEntry = (PWSC_PEER_ENTRY)pListEntry; } RTMP_SEM_UNLOCK(&pWscControl->WscPeerListSemLock); } printk("\n"); } return TRUE; } #endif // CONFIG_AP_SUPPORT // #ifdef CONFIG_STA_SUPPORT INT WscStaShowPeerList( IN PRTMP_ADAPTER pAd, IN PSTRING arg) { PWSC_CTRL pWscControl = NULL; PWSC_PEER_ENTRY pPeerEntry = NULL; PLIST_ENTRY pListEntry = NULL; PLIST_HEADER pWscEnList = NULL; pWscControl = &pAd->StaCfg.WscControl; pWscEnList = &pWscControl->WscPeerList; RTMP_SEM_LOCK(&pWscControl->WscPeerListSemLock); if (pWscEnList->size != 0) { RTMP_SEM_UNLOCK(&pWscControl->WscPeerListSemLock); WscMaintainPeerList(pAd, pWscControl); RTMP_SEM_LOCK(&pWscControl->WscPeerListSemLock); pListEntry = pWscEnList->pHead; pPeerEntry = (PWSC_PEER_ENTRY)pListEntry; while (pPeerEntry != NULL) { printk("MAC:%02x:%02x:%02x:%02x:%02x:%02x\tReveive Time:%lu\n", pPeerEntry->mac_addr[0], pPeerEntry->mac_addr[1], pPeerEntry->mac_addr[2], pPeerEntry->mac_addr[3], pPeerEntry->mac_addr[4], pPeerEntry->mac_addr[5], pPeerEntry->receive_time); pListEntry = pListEntry->pNext; pPeerEntry = (PWSC_PEER_ENTRY)pListEntry; } } RTMP_SEM_UNLOCK(&pWscControl->WscPeerListSemLock); printk("\n"); return TRUE; } #endif // CONFIG_STA_SUPPORT // VOID WscMaintainPeerList( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWpsCtrl) { PWSC_PEER_ENTRY pPeerEntry = NULL; PLIST_ENTRY pListEntry = NULL, pTempListEntry = NULL; PLIST_HEADER pWscEnList = NULL; ULONG now_time = 0; RTMP_SEM_LOCK(&pWpsCtrl->WscPeerListSemLock); pWscEnList = &pWpsCtrl->WscPeerList; NdisGetSystemUpTime(&now_time); pListEntry = pWscEnList->pHead; pPeerEntry = (PWSC_PEER_ENTRY)pListEntry; while (pPeerEntry != NULL) { if (RTMP_TIME_AFTER(now_time, pPeerEntry->receive_time + (30 * OS_HZ))) { pTempListEntry = pListEntry->pNext; delEntryList(pWscEnList, pListEntry); os_free_mem(pAd, pPeerEntry); pListEntry = pTempListEntry; } else pListEntry = pListEntry->pNext; pPeerEntry = (PWSC_PEER_ENTRY)pListEntry; } RTMP_SEM_UNLOCK(&pWpsCtrl->WscPeerListSemLock); return; } VOID WscDelListEntryByMAC( PLIST_HEADER pWscEnList, IN PUCHAR pMacAddr) { PLIST_ENTRY pListEntry = NULL; pListEntry = (PLIST_ENTRY)WscFindPeerEntry(pWscEnList, pMacAddr); if (pListEntry) { DBGPRINT(RT_DEBUG_TRACE, ("WscDelListEntryByMAC : pMacAddr = %02X:%02X:%02X:%02X:%02X:%02X\n", PRINT_MAC(pMacAddr))); delEntryList(pWscEnList, pListEntry); os_free_mem(NULL, pListEntry); } } VOID WscAssignEntryMAC( IN PRTMP_ADAPTER pAd, IN PWSC_CTRL pWpsCtrl) { PWSC_PEER_ENTRY pPeerEntry = NULL; WscMaintainPeerList(pAd, pWpsCtrl); RTMP_SEM_LOCK(&pWpsCtrl->WscPeerListSemLock); pPeerEntry = (PWSC_PEER_ENTRY)pWpsCtrl->WscPeerList.pHead; NdisZeroMemory(pWpsCtrl->EntryAddr, MAC_ADDR_LEN); if (pPeerEntry) { NdisMoveMemory(pWpsCtrl->EntryAddr, pPeerEntry->mac_addr, MAC_ADDR_LEN); } RTMP_SEM_UNLOCK(&pWpsCtrl->WscPeerListSemLock); } /* Get WSC IE data from WSC Peer by Tag. */ BOOLEAN WscGetDataFromPeerByTag( IN PRTMP_ADAPTER pAd, IN PUCHAR pIeData, IN INT IeDataLen, IN USHORT WscTag, OUT PUCHAR pWscBuf, OUT PUSHORT pWscBufLen) { PUCHAR pData = pIeData; INT Len = 0; USHORT DataLen = 0; PWSC_IE pWscIE; Len = IeDataLen; while (Len > 0) { WSC_IE WscIE; NdisMoveMemory(&WscIE, pData, sizeof(WSC_IE)); // Check for WSC IEs pWscIE = &WscIE; if (be2cpu16(pWscIE->Type) == WscTag) { DataLen = be2cpu16(pWscIE->Length); if (pWscBufLen) *pWscBufLen = DataLen; NdisMoveMemory(pWscBuf, pData + 4, DataLen); return TRUE; } // Set the offset and look for next WSC Tag information // 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); } return FALSE; } #endif /* WSC_INCLUDED */