mirror of
https://github.com/YikeStone/MT7601u.git
synced 2025-08-02 10:54:08 +05:30
11561 lines
347 KiB
C
11561 lines
347 KiB
C
/*
|
|
***************************************************************************
|
|
* 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 <net/iw_handler.h> */
|
|
/*#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> "-"
|
|
<time_mid> "-"
|
|
<time_high_and_version> "-"
|
|
<clock_seq_high_and_reserved>
|
|
<clock_seq_low> "-"
|
|
<node>
|
|
time_low = 4*<hex_octet>
|
|
time_mid = 2*<hex_octet>
|
|
time_high_and_version = 2*<hex_octet>
|
|
clock_seq_high_and_reserved = <hex_octet>
|
|
clock_seq_low = <hex_octet>
|
|
node = 6*<hex_octet>
|
|
hex_octet = <hex_digit> <hex_digit>
|
|
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):
|
|
<SSID string>
|
|
*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; i<MAX_LEN_OF_MAC_TABLE; i++)
|
|
{
|
|
PMAC_TABLE_ENTRY pEntry = &pAdapter->MacTab.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; i<MAX_LEN_OF_MAC_TABLE; i++)
|
|
{
|
|
if (IS_ENTRY_CLIENT(&pAd->MacTab.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; i<pAd->SharedKey[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; i<pAd->ApCfg.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; jjj<pCredentail->KeyLength; 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; jjj<pCredentail->KeyLength; 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 */
|
|
|