Files
Linux_Drivers/osdrv/extdrv/wireless/mediatek/mt7603/common/wsc_v2.c
forum_service 213c880673 add driver of tp、wiegand-gpio and wireless
Change-Id: Ie3c11d9d85cf1a05042f5690ac711856fe8b1ad7
2023-12-22 09:56:05 +08:00

421 lines
10 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_v2.c
*/
#include "rt_config.h"
#ifdef WSC_V2_SUPPORT
#include "wsc_tlv.h"
BOOLEAN WscAppendV2SubItem(
IN UCHAR SubID,
IN PUCHAR pData,
IN UCHAR DataLen,
OUT PUCHAR pOutBuf,
OUT PUCHAR pOutBufLen);
#ifdef CONFIG_AP_SUPPORT
VOID WscOnOff(
IN PRTMP_ADAPTER pAd,
IN INT ApIdx,
IN BOOLEAN bOff)
{
PWSC_V2_INFO pWpsV2Info = &pAd->ApCfg.MBSSID[ApIdx & 0x0F].WscControl.WscV2Info;
if (bOff)
{
/*
AP must not support WEP in WPS V2
*/
pWpsV2Info->bWpsEnable = FALSE;
pAd->ApCfg.MBSSID[ApIdx & 0x0F].WscIEBeacon.ValueLen = 0;
pAd->ApCfg.MBSSID[ApIdx & 0x0F].WscIEProbeResp.ValueLen = 0;
DBGPRINT(RT_DEBUG_TRACE, ("WscOnOff - OFF.\n"));
}
else
{
pWpsV2Info->bWpsEnable = TRUE;
if (pAd->ApCfg.MBSSID[ApIdx & 0x0F].WscControl.WscConfMode != WSC_DISABLE)
{
INT IsAPConfigured;
IsAPConfigured = pAd->ApCfg.MBSSID[ApIdx & 0x0F].WscControl.WscConfStatus;
WscBuildBeaconIE(pAd, IsAPConfigured, FALSE, 0, 0, (ApIdx & 0x0F), NULL, 0, AP_MODE);
WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, IsAPConfigured, FALSE, 0, 0, ApIdx, NULL, 0, AP_MODE);
DBGPRINT(RT_DEBUG_TRACE, ("WscOnOff - ON.\n"));
}
}
DBGPRINT(RT_DEBUG_TRACE, ("WscOnOff - bWpsEnable = %d\n", pWpsV2Info->bWpsEnable));
}
VOID WscAddEntryToAclList(
IN PRTMP_ADAPTER pAd,
IN INT ApIdx,
IN PUCHAR pMacAddr)
{
PRT_802_11_ACL pACL = NULL;
INT i;
BOOLEAN bFound = FALSE;
pACL = &pAd->ApCfg.MBSSID[ApIdx].AccessControlList;
if ((pACL->Policy == 0) ||
(pACL->Policy == 2))
return;
if (pACL->Num >= (MAX_NUM_OF_ACL_LIST - 1))
{
DBGPRINT(RT_DEBUG_WARN, ("The AccessControlList is full, and no more entry can join the list!\n"));
return;
}
for (i=0; i<pACL->Num; i++)
{
if (NdisEqualMemory(pACL->Entry[i].Addr, pMacAddr, MAC_ADDR_LEN))
bFound = TRUE;
}
if (bFound == FALSE)
{
NdisMoveMemory(pACL->Entry[i].Addr, pMacAddr, MAC_ADDR_LEN);
pACL->Num++;
}
}
VOID WscSetupLockTimeout(
IN PVOID SystemSpecific1,
IN PVOID FunctionContext,
IN PVOID SystemSpecific2,
IN PVOID SystemSpecific3)
{
PWSC_CTRL pWscControl = (PWSC_CTRL)FunctionContext;
PRTMP_ADAPTER pAd = NULL;
if (pWscControl == NULL)
return;
pAd = (PRTMP_ADAPTER)pWscControl->pAd;
if (pAd == NULL)
return;
pWscControl->bSetupLock = FALSE;
pWscControl->WscSetupLockTimerRunning = FALSE;
WscBuildBeaconIE(pAd,
pWscControl->WscConfStatus,
FALSE,
0,
0,
(pWscControl->EntryIfIdx & 0xF),
NULL,
0,
AP_MODE);
WscBuildProbeRespIE(pAd,
WSC_MSGTYPE_AP_WLAN_MGR,
pWscControl->WscConfStatus,
FALSE,
0,
0,
pWscControl->EntryIfIdx,
NULL,
0,
AP_MODE);
APUpdateBeaconFrame(pAd, pWscControl->EntryIfIdx & 0x0F);
DBGPRINT(RT_DEBUG_TRACE, ("WscSetupLockTimeout!\n"));
return;
}
VOID WscCheckPinAttackCount(
IN PRTMP_ADAPTER pAd,
IN PWSC_CTRL pWscControl)
{
BOOLEAN bCancelled;
if ((pWscControl->EntryIfIdx & MIN_NET_DEVICE_FOR_APCLI)
#ifdef P2P_SUPPORT
|| (pWscControl->EntryIfIdx & MIN_NET_DEVICE_FOR_P2P_CLI)
#endif /* P2P_SUPPORT */
)
{
/*
APCLI and P2P CLI don't need to do PIN attack checking.
*/
return;
}
/*
If a static PIN is used,
the AP must track multiple failed attempts to authenticate an external Registrar and then enter a lock-down state
(This state is signified by setting the attribute AP Setup Locked to TRUE).
After at most 10 failed, consecutive attempts, with no time limitation, from any number of external Registrars,
the AP shall revert to a locked down state, and the AP shall remain in the locked down state indefinitely
(i.e., until the user intervenes to unlock AP's PIN for use by external Registrars)
*/
pWscControl->PinAttackCount++;
if (pWscControl->PinAttackCount >= pWscControl->MaxPinAttack)
{
pWscControl->bSetupLock = TRUE;
if (pWscControl->WscSetupLockTimerRunning)
{
RTMPCancelTimer(&pWscControl->WscSetupLockTimer, &bCancelled);
pWscControl->WscSetupLockTimerRunning = FALSE;
}
if (pWscControl->PinAttackCount < WSC_LOCK_FOREVER_PIN_ATTACK)
{
pWscControl->WscSetupLockTimerRunning = TRUE;
RTMPSetTimer(&pWscControl->WscSetupLockTimer, pWscControl->SetupLockTime*60*1000);
}
#if 0
/*
Do NOT reset this counter for counting consecutive pin attack with no time limitation. @2014/02/13
Reset this counter after user intervenes to unlock.
*/
pWscControl->PinAttackCount = 0;
#endif
WscBuildBeaconIE(pAd,
pWscControl->WscConfStatus,
FALSE,
0,
0,
(pWscControl->EntryIfIdx & 0xF),
NULL,
0,
AP_MODE);
WscBuildProbeRespIE(pAd,
WSC_MSGTYPE_AP_WLAN_MGR,
pWscControl->WscConfStatus,
FALSE,
0,
0,
pWscControl->EntryIfIdx,
NULL,
0,
AP_MODE);
APUpdateBeaconFrame(pAd, pWscControl->EntryIfIdx & 0x0F);
}
}
#endif /* CONFIG_AP_SUPPORT */
/*
Vendor ID: 0x00372A
Subelements ID (one-octet)
Version2 0x00
AuthorizedMACs 0x01
Network Key Shareable 0x02
Request to Enroll 0x03
Settings Delay Time 0x04
Reserved for future use 0x05 to 0xFF
Length (one-octet) - number of octets in the payload of this subelment
Version2 1B
AuthorizedMACs <=30B
Network Key Shareable Bool
Request to Enroll Bool
Settings Delay Time 1B
*/
BOOLEAN WscGenV2Msg(
IN PWSC_CTRL pWpsCtrl,
IN BOOLEAN bSelRegistrar,
IN PUCHAR pAuthorizedMACs,
IN INT AuthorizedMACsLen,
OUT UCHAR **pOutBuf,
OUT INT *pOutBufLen)
{
PUCHAR pWscV2Msg = NULL;
USHORT WscV2MsgLen = 0;
PWSC_REG_DATA pReg = &pWpsCtrl->RegData;
INT templen = 0;
os_alloc_mem(NULL, (UCHAR **)&pWscV2Msg, 128);
if (pWscV2Msg)
{
UCHAR TmpLen = 0;
pWscV2Msg[0] = 0x00;
pWscV2Msg[1] = 0x37;
pWscV2Msg[2] = 0x2A;
/* Version2 */
WscAppendV2SubItem(WFA_EXT_ID_VERSION2, &pReg->SelfInfo.Version2, 1, pWscV2Msg+3, &TmpLen);
WscV2MsgLen += (3 + (USHORT)TmpLen);
if (bSelRegistrar)
{
/*
Authorized MACs
Registrars (both internal and external) shall add the AuthorizedMACs subelement,
this applies to all Configuration Methods, including PIN, PBC and NFC.
*/
if (pAuthorizedMACs)
{
WscAppendV2SubItem( WFA_EXT_ID_AUTHORIZEDMACS,
pAuthorizedMACs,
AuthorizedMACsLen,
pWscV2Msg+WscV2MsgLen,
&TmpLen );
WscV2MsgLen += (USHORT)TmpLen;
}
else
{
WscAppendV2SubItem( WFA_EXT_ID_AUTHORIZEDMACS,
BROADCAST_ADDR,
MAC_ADDR_LEN,
pWscV2Msg+WscV2MsgLen,
&TmpLen );
WscV2MsgLen += (USHORT)TmpLen;
}
}
templen = AppendWSCTLV(WSC_ID_VENDOR_EXT, (*pOutBuf), (UINT8 *)pWscV2Msg, WscV2MsgLen);
(*pOutBuf) += templen;
(*pOutBufLen) += templen;
os_free_mem(NULL, pWscV2Msg);
return TRUE;
}
return FALSE;
}
BOOLEAN WscAppendV2SubItem(
IN UCHAR SubID,
IN PUCHAR pData,
IN UCHAR DataLen,
OUT PUCHAR pOutBuf,
OUT PUCHAR pOutBufLen)
{
PUCHAR pBuf = NULL;
os_alloc_mem(NULL, &pBuf, DataLen + 10);
if (pBuf)
{
pBuf[0] = SubID;
pBuf[1] = DataLen;
NdisMoveMemory(pBuf+2, pData, DataLen);
*pOutBufLen = (DataLen + 2);
NdisMoveMemory(pOutBuf, pBuf, *pOutBufLen);
os_free_mem(NULL, pBuf);
return TRUE;
}
return FALSE;
}
BOOLEAN WscParseV2SubItem(
IN UCHAR SubID,
IN PUCHAR pData,
IN USHORT DataLen,
OUT PUCHAR pOutBuf,
OUT PUCHAR pOutBufLen)
{
PEID_STRUCT pEid;
USHORT Length = 0;
pEid = (PEID_STRUCT) (pData + 3);
hex_dump("WscParseV2SubItem - pData", (pData+3), DataLen-3);
while ((Length + 2 + pEid->Len) <= (DataLen-3))
{
if (pEid->Eid == SubID)
{
*pOutBufLen = pEid->Len;
NdisMoveMemory(pOutBuf, &pEid->Octet[0], pEid->Len);
return TRUE;
}
Length = Length + 2 + pEid->Len;
pEid = (PEID_STRUCT)((UCHAR*)pEid + 2 + pEid->Len);
}
return FALSE;
}
VOID WscSendEapFragAck(
IN PRTMP_ADAPTER pAdapter,
IN PWSC_CTRL pWscControl,
IN PMAC_TABLE_ENTRY pEntry)
{
if (pEntry == NULL)
{
ASSERT(pEntry!=NULL);
return;
}
if (IS_ENTRY_CLIENT(pEntry))
{
pWscControl->bWscLastOne = TRUE;
if (pAdapter->OpMode == OPMODE_AP)
WscSendMessage(pAdapter, WSC_OPCODE_FRAG_ACK, NULL, 0, pWscControl, AP_MODE, EAP_CODE_REQ);
else
{
if (ADHOC_ON(pAdapter) && (pWscControl->WscConfMode == WSC_REGISTRAR))
WscSendMessage(pAdapter, WSC_OPCODE_FRAG_ACK, NULL, 0, pWscControl, STA_MODE, EAP_CODE_REQ);
else
WscSendMessage(pAdapter, WSC_OPCODE_FRAG_ACK, NULL, 0, pWscControl, STA_MODE, EAP_CODE_RSP);
}
}
else if (IS_ENTRY_APCLI(pEntry))
WscSendMessage(pAdapter, WSC_OPCODE_FRAG_ACK, NULL, 0, pWscControl, AP_CLIENT_MODE, EAP_CODE_REQ);
}
VOID WscSendEapFragData(
IN PRTMP_ADAPTER pAdapter,
IN PWSC_CTRL pWscControl,
IN PMAC_TABLE_ENTRY pEntry)
{
INT DataLen = 0;
PUCHAR pData = NULL;
if (pEntry == NULL)
{
ASSERT(pEntry!=NULL);
return;
}
pData = pWscControl->pWscCurBufIdx;
pWscControl->bWscLastOne = TRUE;
if (pWscControl->WscTxBufLen > pWscControl->WscFragSize)
{
pWscControl->bWscLastOne = FALSE;
DataLen = pWscControl->WscFragSize;
pWscControl->WscTxBufLen -= pWscControl->WscFragSize;
pWscControl->pWscCurBufIdx = (pWscControl->pWscCurBufIdx + pWscControl->WscFragSize);
}
else
{
DataLen = pWscControl->WscTxBufLen;
pWscControl->pWscCurBufIdx = NULL;
pWscControl->WscTxBufLen = 0;
}
#ifdef CONFIG_AP_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_AP(pAdapter)
{
if (IS_ENTRY_APCLI(pEntry))
WscSendMessage(pAdapter, WSC_OPCODE_MSG, pData, DataLen, pWscControl, AP_CLIENT_MODE, EAP_CODE_RSP);
else
WscSendMessage(pAdapter, WSC_OPCODE_MSG, pData, DataLen, pWscControl, AP_MODE, EAP_CODE_REQ);
}
#endif // CONFIG_AP_SUPPORT //
#ifdef CONFIG_STA_SUPPORT
IF_DEV_CONFIG_OPMODE_ON_STA(pAdapter)
WscSendMessage(pAdapter, WSC_OPCODE_MSG, pData, DataLen, pWscControl, STA_MODE, EAP_CODE_RSP);
#endif // CONFIG_STA_SUPPORT //
}
#endif /* WSC_V2_SUPPORT */