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

933 lines
27 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/*
***************************************************************************
* 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_NFC_SUPPORT
extern UINT8 WPS_DH_G_VALUE[1];
extern UINT8 WPS_DH_P_VALUE[192];
typedef struct _NFC_CMD_INFO {
USHORT vendor_id;
UCHAR action;
UCHAR type;
USHORT data_len;
UCHAR data[0];
} NFC_CMD_INFO;
/*
Packet Type: PACKET_OTHERHOST
Packet Protocol: 0x6605
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Vendor Id | Action | Type |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Length | Data¡K¡K
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-
Vendor: 0x14C3
Action: b¡¦<7:6>: 0x0 ¡V To NFC, 0x1 ¡V From NFC
b¡¦<5:0>: 0x00 ¡V Get, 0x01 - Set
Type:
0 ¡V Command Result (1 byte)
1 - Configuration (WSC TLV)
2 ¡V Password (32 bytes)
3 ¡V IP address (4 bytes)
4 ¡V RTSP port (4 bytes)
5 ¡V NFC Status (1 byte)
b'0: 1 - ON, 0 - OFF
b'1: 1 - nfc device detect
6 ¡V Wireless Radio Status (1byte)
*/
#define ETH_MTK_NFC 0x6605
#define NFC_VENDOR_ID 0x14C3
VOID NfcCommand(
IN PRTMP_ADAPTER pAd,
IN UCHAR Action,
IN UCHAR Type,
IN SHORT DataLen,
IN PUCHAR pData)
{
PNET_DEV pNetDev = pAd->net_dev;
UCHAR *pBuffer = NULL;
USHORT len;
USHORT vendor_id = NFC_VENDOR_ID, type = ETH_MTK_NFC, net_type;
UCHAR Header802_3[LENGTH_802_3];
UCHAR SrcMacAddr[MAC_ADDR_LEN] = {0x00, 0x00, 0x00, 0x00, 0x66, 0x05};
struct wifi_dev *wdev;
BSS_STRUCT *pMbss;
#if 0
len = sizeof(vendor_id) + sizeof(Action) + sizeof(Type) + sizeof(USHORT);
#else
len = sizeof(vendor_id) + sizeof(Action) + sizeof(Type) + sizeof(USHORT) + LENGTH_802_3;
#endif
if (DataLen > 0)
len += DataLen;
os_alloc_mem(pAd, (UCHAR **)&pBuffer, (len*sizeof(UCHAR)));
if (pBuffer == NULL)
return;
pMbss = &pAd->ApCfg.MBSSID[0];
wdev = &pMbss->wdev;
NdisZeroMemory(pBuffer, len);
#if 1
NdisZeroMemory(&Header802_3[0], LENGTH_802_3);
NdisMoveMemory(&Header802_3[0], wdev->bssid, MAC_ADDR_LEN);
NdisMoveMemory((&Header802_3[0] + MAC_ADDR_LEN), &SrcMacAddr[0], MAC_ADDR_LEN);
net_type = htons(type);
NdisMoveMemory((&Header802_3[0] + MAC_ADDR_LEN * 2), &net_type, LENGTH_802_3_TYPE);
//hex_dump("Header802_3", &Header802_3[0], LENGTH_802_3);
#endif
#if 0
NdisMoveMemory(pBuf, &vendor_id, sizeof(vendor_id));
NdisMoveMemory(pBuf+sizeof(vendor_id), &Action, sizeof(Action));
NdisMoveMemory(pBuf+sizeof(vendor_id)+sizeof(Action), &Type, sizeof(Type));
NdisMoveMemory(pBuf+sizeof(vendor_id)+sizeof(Action)+sizeof(Type), &DataLen, sizeof(USHORT));
if ((DataLen > 0) && (pData != NULL))
NdisMoveMemory(pBuf+sizeof(vendor_id)+sizeof(Action)+sizeof(Type)+sizeof(USHORT), pData, DataLen);
#else
NdisMoveMemory(pBuffer, &Header802_3[0], LENGTH_802_3);
NdisMoveMemory(pBuffer+LENGTH_802_3, &vendor_id, sizeof(vendor_id));
NdisMoveMemory(pBuffer+LENGTH_802_3+sizeof(vendor_id), &Action, sizeof(Action));
NdisMoveMemory(pBuffer+LENGTH_802_3+sizeof(vendor_id)+sizeof(Action), &Type, sizeof(Type));
NdisMoveMemory(pBuffer+LENGTH_802_3+sizeof(vendor_id)+sizeof(Action)+sizeof(Type), &DataLen, sizeof(USHORT));
if ((DataLen > 0) && (pData != NULL))
NdisMoveMemory(pBuffer+LENGTH_802_3+sizeof(vendor_id)+sizeof(Action)+sizeof(Type)+sizeof(USHORT), pData, DataLen);
#endif
hex_dump("NfcCommand", pBuffer, len);
RtmpOSNotifyRawData(pNetDev, pBuffer, len, 0, ETH_MTK_NFC);
os_free_mem(NULL,pBuffer);
return;
}
VOID NfcGenRandomPasswd(
IN PRTMP_ADAPTER pAd,
IN PWSC_CTRL pWscCtrl)
{
UCHAR idx = 0;
NdisZeroMemory(&pWscCtrl->NfcPasswd[0], 32);
for (idx = 0; idx < NFC_DEV_PASSWD_LEN; idx++)
{
pWscCtrl->NfcPasswd[idx] = RandomByte(pAd);
}
pWscCtrl->NfcPasswdLen = NFC_DEV_PASSWD_LEN;
return;
}
#define NFC_WSC_TLV_SIZE 512
INT NfcBuildWscProfileTLV(
IN PRTMP_ADAPTER pAd,
IN PWSC_CTRL pWscCtrl,
OUT UCHAR *pbuf,
OUT USHORT *pBufLen)
{
INT Status = NDIS_STATUS_SUCCESS;
PWSC_CREDENTIAL pCredential = NULL;
UCHAR apidx = pWscCtrl->EntryIfIdx;
UCHAR *TB = NULL;
UCHAR *pData = NULL, *pSrcData = NULL;
INT CerLen = 0;
USHORT AuthType = 0;
USHORT EncrType = 0;
PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscCtrl->RegData;
INT Len = 0, templen = 0;
struct wifi_dev *wdev;
BSS_STRUCT *pMbss;
#ifdef WSC_V2_SUPPORT
PWSC_TLV pWscTLV = &pWscCtrl->WscV2Info.ExtraTlv;
#endif /* WSC_V2_SUPPORT */
os_alloc_mem(pAd, (UCHAR **)&pData, (NFC_WSC_TLV_SIZE*sizeof(UCHAR)));
if (pData == NULL)
{
return NDIS_STATUS_RESOURCES;
}
os_alloc_mem(pAd, (UCHAR **)&TB, (256*sizeof(UCHAR)));
if (TB == NULL)
{
os_free_mem(NULL, pData);
return NDIS_STATUS_RESOURCES;
}
pMbss = &pAd->ApCfg.MBSSID[apidx];
wdev = &pMbss->wdev;
pSrcData = pData;
NdisZeroMemory(pData, NFC_WSC_TLV_SIZE);
NdisZeroMemory(&TB[0], 256);
WscCreateProfileFromCfg(pAd, REGISTRAR_ACTION | AP_MODE, pWscCtrl, &pWscCtrl->WscProfile);
pCredential = &pAd->ApCfg.MBSSID[apidx].WscControl.WscProfile.Profile[0];
#if 0
// Version
// 1. Version
templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
pData += templen;
Len += templen;
#endif
// Credential
CerLen += AppendWSCTLV(WSC_ID_NW_INDEX, &TB[0], (PUCHAR)"1", 0);
AuthType = cpu2be16(pCredential->AuthType);
EncrType = cpu2be16(pCredential->EncrType);
CerLen += AppendWSCTLV(WSC_ID_SSID, &TB[CerLen], pCredential->SSID.Ssid, pCredential->SSID.SsidLength);
CerLen += AppendWSCTLV(WSC_ID_AUTH_TYPE, &TB[CerLen], (UINT8 *)&AuthType, 0);
CerLen += AppendWSCTLV(WSC_ID_ENCR_TYPE, &TB[CerLen], (UINT8 *)&EncrType, 0);
CerLen += AppendWSCTLV(WSC_ID_NW_KEY_INDEX, &TB[CerLen], &pCredential->KeyIndex, 0);
CerLen += AppendWSCTLV(WSC_ID_NW_KEY, &TB[CerLen], pCredential->Key, pCredential->KeyLength);
CerLen += AppendWSCTLV(WSC_ID_MAC_ADDR, &TB[CerLen], wdev->bssid, 0);
// Prepare plain text
// Reguired attribute item in M8 if Enrollee is STA.
templen = AppendWSCTLV(WSC_ID_CREDENTIAL, pData, TB, CerLen);
pData += templen;
Len += templen;
/* Optional items. RF_Band, AP_Channel, MAC_Address */
UCHAR RF_Band;
if (pAd->CommonCfg.Channel > 14)
RF_Band = 0x02; /* 5.0GHz */
else
RF_Band = 0x01; /* 2.4GHz */
templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, &RF_Band, 0);
pData += templen;
Len += templen;
USHORT Channel = 0;
Channel = pAd->CommonCfg.Channel;
#ifdef RT_BIG_ENDIAN
Channel = SWAP16(Channel);
#endif /* RT_BIG_ENDIAN */
templen = AppendWSCTLV(WSC_ID_AP_CHANNEL, pData, (UINT8 *)&Channel, 0);
pData += templen;
Len += templen;
templen = AppendWSCTLV(WSC_ID_MAC_ADDR, pData, wdev->bssid, 0);
pData += templen;
Len += templen;
#ifdef WSC_V2_SUPPORT
if (pWscCtrl->WscV2Info.bEnableWpsV2)
{
/* Version2 */
WscGenV2Msg(pWscCtrl,
FALSE,
NULL,
0,
&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 //
hex_dump("NfcBuildWscProfileTLV - pData", pSrcData, Len);
if (pbuf && (Len < NFC_WSC_TLV_SIZE))
{
NdisMoveMemory(pbuf, pSrcData, Len);
*pBufLen = (USHORT)Len;
hex_dump("NfcBuildWscProfileTLV", pbuf, *pBufLen);
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("%s: (Len=%d)\n", __FUNCTION__, Len));
Status = NDIS_STATUS_RESOURCES;
}
os_free_mem(NULL, pSrcData);
os_free_mem(NULL, TB);
return Status;
}
INT NfcBuildOOBDevPasswdTLV(
IN PRTMP_ADAPTER pAd,
IN PWSC_CTRL pWscCtrl,
IN UCHAR HandoverType,
OUT UCHAR *pbuf,
OUT USHORT *pBufLen)
{
INT Status = NDIS_STATUS_SUCCESS;
UCHAR *TB = NULL;;
PUCHAR pData = NULL, pSrcData = NULL;
USHORT PasswdID = 0, len;
PWSC_REG_DATA pReg = (PWSC_REG_DATA) &pWscCtrl->RegData;
INT Len = 0, templen = 0;
INT DH_Len = 0, idx;
UCHAR HashData[SHA256_DIGEST_SIZE];
INT nfc_dev_passwd_len=0;
#ifdef WSC_V2_SUPPORT
PWSC_TLV pWscTLV = &pWscCtrl->WscV2Info.ExtraTlv;
#endif /* WSC_V2_SUPPORT */
os_alloc_mem(pAd, (UCHAR **)&pData, (NFC_WSC_TLV_SIZE*sizeof(UCHAR)));
if (pData == NULL)
{
return NDIS_STATUS_RESOURCES;
}
os_alloc_mem(pAd, (UCHAR **)&TB, (128*sizeof(UCHAR)));
if (pData == NULL)
{
os_free_mem(NULL, pData);
return NDIS_STATUS_RESOURCES;
}
DH_Len = sizeof(pWscCtrl->RegData.Pke);
/*
Enrollee 192 random bytes for DH key generation
*/
for (idx = 0; idx < 192; idx++)
pWscCtrl->RegData.EnrolleeRandom[idx] = RandomByte(pAd);
RT_DH_PublicKey_Generate (
WPS_DH_G_VALUE, sizeof(WPS_DH_G_VALUE),
WPS_DH_P_VALUE, sizeof(WPS_DH_P_VALUE),
pWscCtrl->RegData.EnrolleeRandom, sizeof(pWscCtrl->RegData.EnrolleeRandom),
pWscCtrl->RegData.Pke, (UINT *) &DH_Len);
/* For Handover case, We may as Registrar
So keep the same public key for Registrar */
RTMPMoveMemory(pWscCtrl->RegData.Pkr, pWscCtrl->RegData.Pke, DH_Len);
hex_dump("Pkr", pWscCtrl->RegData.Pkr, DH_Len);
hex_dump("Pke", pWscCtrl->RegData.Pkr, DH_Len);
RT_SHA256(&pWscCtrl->RegData.Pke[0], 192, &HashData[0]);
RTMPMoveMemory(&pWscCtrl->NfcPasswdHash[0], &HashData[0], NFC_DEV_PASSWD_HASH_LEN);
hex_dump("NfcBuildOOBDevPasswdTLV - Public Key HashData", &HashData[0], 20);
if (HandoverType == TYPE_PASSWDHO_S || HandoverType == TYPE_PASSWDHO_R)
{
PasswdID = DEV_PASS_ID_NFC_HANDOVER;
pWscCtrl->NfcPasswdID = cpu2be16(PasswdID);
NdisZeroMemory(&pWscCtrl->NfcPasswd[0], 32);
pWscCtrl->NfcPasswdLen = NFC_DEV_PASSWD_LEN;
}
else
{
PasswdID = (RandomByte(pAd) << 8) + RandomByte(pAd);
if (PasswdID < 0x10)
PasswdID = 0x10;
pWscCtrl->NfcPasswdID = cpu2be16(PasswdID);
NfcGenRandomPasswd(pAd, pWscCtrl);
hex_dump("NfcBuildOOBDevPasswdTLV - NfcPasswd", &pWscCtrl->NfcPasswd[0], NFC_DEV_PASSWD_LEN);
}
pSrcData = pData;
NdisZeroMemory(pData, NFC_WSC_TLV_SIZE);
NdisZeroMemory(&TB[0], 128);
#if 1
if (HandoverType == TYPE_PASSWDHO_R || HandoverType == TYPE_PASSWDHO_S)
{
/* Reserv for "Length of WSC attribute" */
pData += 2;
}
#endif
#if 0
// Version
templen = AppendWSCTLV(WSC_ID_VERSION, pData, &pReg->SelfInfo.Version, 0);
pData += templen;
Len += templen;
#endif
hex_dump("NfcBuildOOBDevPasswdTLV - 1 pSrcData", pSrcData, Len);
NdisMoveMemory(&TB[0], &HashData[0], NFC_DEV_PASSWD_HASH_LEN);
NdisMoveMemory(&TB[20], &pWscCtrl->NfcPasswdID, sizeof(pWscCtrl->NfcPasswdID));
if (HandoverType == TYPE_PASSWORD)
{
/* New SPEC Handover remove this part. */
NdisMoveMemory(&TB[22], &pWscCtrl->NfcPasswd[0], NFC_DEV_PASSWD_LEN);
nfc_dev_passwd_len = NFC_DEV_PASSWD_LEN;
}
templen = AppendWSCTLV(WSC_ID_OOB_DEV_PWD, pData, &TB[0], NFC_DEV_PASSWD_HASH_LEN+sizeof(PasswdID)+nfc_dev_passwd_len);
pData += templen;
Len += templen;
hex_dump("NfcBuildOOBDevPasswdTLV - 2 pSrcData", pSrcData, Len);
if (HandoverType == TYPE_PASSWDHO_S) /* Build for Handover Select Message */
{
templen = AppendWSCTLV(WSC_ID_SSID, pData, pAd->ApCfg.MBSSID[0].Ssid, pAd->ApCfg.MBSSID[0].SsidLen);
pData += templen;
Len += templen;
/* Optional items. RF_Band, AP_Channel and MAC_Address */
UCHAR RF_Band;
if (pAd->CommonCfg.Channel > 14)
RF_Band = 0x02; /* 5.0GHz */
else
RF_Band = 0x01; /* 2.4GHz */
templen = AppendWSCTLV(WSC_ID_RF_BAND, pData, &RF_Band, 0);
pData += templen;
Len += templen;
USHORT Channel = 0;
Channel = pAd->CommonCfg.Channel;
#ifdef RT_BIG_ENDIAN
Channel = SWAP16(Channel);
#endif /* RT_BIG_ENDIAN */
templen = AppendWSCTLV(WSC_ID_AP_CHANNEL, pData, (UINT8 *)&Channel, 0);
pData += templen;
Len += templen;
templen = AppendWSCTLV(WSC_ID_MAC_ADDR, pData, pAd->CommonCfg.Bssid, 0);
pData += templen;
Len += templen;
}
else if (HandoverType == TYPE_PASSWDHO_R) /* Build for Handover Request Message */
{
templen = AppendWSCTLV(WSC_ID_UUID_E, pData, &pWscCtrl->Wsc_Uuid_E[0], 0);
pData += templen;
Len += templen;
}
#ifdef WSC_V2_SUPPORT
if (pWscCtrl->WscV2Info.bEnableWpsV2)
{
/* Version2 */
WscGenV2Msg(pWscCtrl,
FALSE,
NULL,
0,
&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 1
if (HandoverType == TYPE_PASSWDHO_R || HandoverType == TYPE_PASSWDHO_S)
{
/*Assign for "Length of WSC attribute" */
len = cpu2be16(Len);
memcpy(pSrcData, &len, 2);
hex_dump("NfcBuildOOBDevPasswdTLV - pSrcData", pSrcData, Len+2);
}
else
hex_dump("NfcBuildOOBDevPasswdTLV - pSrcData", pSrcData, Len);
#endif
if (pbuf && (Len < NFC_WSC_TLV_SIZE))
{
if (HandoverType == TYPE_PASSWDHO_R || HandoverType == TYPE_PASSWDHO_S)
{
NdisMoveMemory(pbuf, pSrcData, Len+2);
*pBufLen = (USHORT)Len+2;
}
else
{
NdisMoveMemory(pbuf, pSrcData, Len);
*pBufLen = (USHORT)Len;
}
hex_dump("NfcBuildOOBDevPasswdTLV", pbuf, *pBufLen);
}
else
{
DBGPRINT(RT_DEBUG_TRACE, ("%s: (Len=%d)\n", __FUNCTION__, Len));
Status = NDIS_STATUS_RESOURCES;
}
os_free_mem(NULL, pSrcData);
os_free_mem(NULL, TB);
return Status;
}
static BOOLEAN NfcProcessPasswdTV(
IN PRTMP_ADAPTER pAdapter,
IN PUCHAR pPlainData,
IN INT PlainLength,
IN PWSC_CTRL pWscCtrl,
IN UCHAR bHandOver)
{
USHORT WscType, WscLen;
PUCHAR pData;
INT DH_Len = 0, idx;
pData = pPlainData;
hex_dump("NfcProcessPasswdTV - PlainData", pPlainData, PlainLength);
// Start to process WSC IEs within credential
if (bHandOver)
{
pData +=2; /* Skip length of WSC attribute */
PlainLength -= 2;
}
while (PlainLength > 4)
{
WSC_IE TLV_Recv;
memcpy((UINT8 *)&TLV_Recv, pData, 4);
WscType = be2cpu16(TLV_Recv.Type);
WscLen = be2cpu16(TLV_Recv.Length);
pData += 4;
PlainLength -= 4;
// Parse M2 WSC type and store to RegData structure
switch (WscType)
{
case WSC_ID_OOB_DEV_PWD:
hex_dump("NfcProcessPasswdTV - WSC_ID_OOB_DEV_PWD", pData, WscLen);
NdisMoveMemory(&pWscCtrl->PeerNfcPasswdHash[0], pData, NFC_DEV_PASSWD_HASH_LEN);
NdisMoveMemory(&pWscCtrl->PeerNfcPasswdID, pData+20, sizeof(pWscCtrl->PeerNfcPasswdID));
pWscCtrl->PeerNfcPasswdLen = WscLen - 2 - NFC_DEV_PASSWD_HASH_LEN;
if (pWscCtrl->PeerNfcPasswdLen > NFC_DEV_PASSWD_LEN)
{
DBGPRINT(RT_DEBUG_TRACE, ("%s --> PeerNfcPasswdLen(%d) > NFC_DEV_PASSWD_LEN(%d)\n",
__FUNCTION__, pWscCtrl->PeerNfcPasswdLen, NFC_DEV_PASSWD_LEN));
pWscCtrl->PeerNfcPasswdLen = NFC_DEV_PASSWD_LEN;
}
if (bHandOver== TRUE)
{
if (pWscCtrl->PeerNfcPasswdID != DEV_PASS_ID_NFC_HANDOVER)
DBGPRINT(RT_DEBUG_TRACE, ("%s --> PeerNfcPasswdID(%04x) it should 0x0007 \n",
__FUNCTION__, pWscCtrl->PeerNfcPasswdID));
}
NdisMoveMemory(&pWscCtrl->PeerNfcPasswd[0], pData+20+sizeof(pWscCtrl->PeerNfcPasswdID), pWscCtrl->PeerNfcPasswdLen);
hex_dump("PeerNfcPasswd", pWscCtrl->PeerNfcPasswd, pWscCtrl->PeerNfcPasswdLen);
if (bHandOver==FALSE)
{
/* Due to M3 & M4 use the same WscGenPSK1 function,
need copy to NfcPasswd, too */
NdisMoveMemory(&pWscCtrl->NfcPasswd[0], &pWscCtrl->PeerNfcPasswd[0], pWscCtrl->PeerNfcPasswdLen);
pWscCtrl->NfcPasswdLen = pWscCtrl->PeerNfcPasswdLen;
}
break;
case WSC_ID_UUID_E:
NdisMoveMemory(pWscCtrl->RegData.PeerInfo.Uuid, pData, WscLen);
break;
case WSC_ID_SSID:
hex_dump("NfcProcessPasswdTV - WSC_ID_SSID", pData, WscLen);
break;
case WSC_ID_VENDOR_EXT:
hex_dump("NfcProcessPasswdTV - WSC_ID_VENDOR_EXT", pData, WscLen);
break;
default:
DBGPRINT(RT_DEBUG_TRACE, ("%s --> Unknown IE 0x%04x\n", __FUNCTION__, WscType));
break;
}
// Offset to net WSC Ie
pData += WscLen;
PlainLength -= WscLen;
}
DBGPRINT(RT_DEBUG_TRACE, ("%s --> bHandOver=%d", __FUNCTION__, bHandOver));
if (bHandOver== FALSE)
{
DH_Len = sizeof(pWscCtrl->RegData.Pkr);
// Enrollee 192 random bytes for DH key generation
for (idx = 0; idx < 192; idx++)
pWscCtrl->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),
pWscCtrl->RegData.EnrolleeRandom, sizeof(pWscCtrl->RegData.EnrolleeRandom),
pWscCtrl->RegData.Pkr, (UINT *) &DH_Len);
hex_dump("Pkr", pWscCtrl->RegData.Pkr, 192);
}
return TRUE;
}
VOID NfcParseRspCommand(
IN PRTMP_ADAPTER pAd,
IN PUCHAR pData,
IN USHORT DataLen)
{
NFC_CMD_INFO *pNfcCmdInfo = NULL;
BOOLEAN bSetFromNfc = FALSE;
PWSC_CTRL pWscCtrl = &pAd->ApCfg.MBSSID[0].WscControl;
DBGPRINT(RT_DEBUG_TRACE, ("====> %s\n", __FUNCTION__));
hex_dump("Packet", pData, DataLen);
os_alloc_mem(pAd, (UCHAR **)&pNfcCmdInfo, (DataLen*sizeof(UCHAR)));
if (pNfcCmdInfo)
{
NdisMoveMemory(pNfcCmdInfo, pData, DataLen);
hex_dump("Packet", &pNfcCmdInfo->data[0], pNfcCmdInfo->data_len);
bSetFromNfc = ((pNfcCmdInfo->action & 0x41) == 0x41);
DBGPRINT(RT_DEBUG_TRACE, ("==> vendor_id: 0x%04x, action = 0x%0x, type = %d, data_len = %u, bSetFromNfc = %d\n",
pNfcCmdInfo->vendor_id, pNfcCmdInfo->action, pNfcCmdInfo->type, pNfcCmdInfo->data_len, bSetFromNfc));
switch(pNfcCmdInfo->type)
{
case TYPE_CMD_RESULT:
DBGPRINT(RT_DEBUG_TRACE, ("TYPE_CMD_RESULT(=%d): Command result = %d\n", pNfcCmdInfo->type, pNfcCmdInfo->data[0]));
break;
case TYPE_CONFIGURATION:
DBGPRINT(RT_DEBUG_TRACE, ("TYPE_CONFIGURATION(=%d)\n", pNfcCmdInfo->type));
if (bSetFromNfc)
{
if (pNfcCmdInfo->data_len != 1)
{
/*
Receive Configuration from NFC daemon.
*/
if (WscProcessCredential(pAd, &pNfcCmdInfo->data[0], pNfcCmdInfo->data_len, pWscCtrl) == FALSE)
{
DBGPRINT(RT_DEBUG_TRACE, ("ProcessCredential fail..\n"));
}
else
{
if ((pAd->OpMode == OPMODE_AP) && (pWscCtrl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED))
{
pWscCtrl->WscConfStatus = WSC_SCSTATE_CONFIGURED;
WscBuildBeaconIE(pAd, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, 0, NULL, 0, AP_MODE);
WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, 0, NULL, 0, AP_MODE);
APUpdateAllBeaconFrame(pAd);
}
if (pWscCtrl->WscUpdatePortCfgTimerRunning)
{
BOOLEAN bCancel;
RTMPCancelTimer(&pWscCtrl->WscUpdatePortCfgTimer, &bCancel);
}
else
pWscCtrl->WscUpdatePortCfgTimerRunning = TRUE;
RTMPSetTimer(&pWscCtrl->WscUpdatePortCfgTimer, 1000);
}
}
}
else
{
Set_NfcConfigurationToken_Proc(pAd, "1");
}
break;
case TYPE_PASSWORD:
DBGPRINT(RT_DEBUG_TRACE, ("TYPE_PASSWORD(=%d)\n", pNfcCmdInfo->type));
if (bSetFromNfc)
{
if (pNfcCmdInfo->data_len != 1)
{
/*
Receive Passwd from NFC daemon.
*/
NfcProcessPasswdTV(pAd, &pNfcCmdInfo->data[0], pNfcCmdInfo->data_len, pWscCtrl, FALSE);
WscGetConfWithoutTrigger(pAd, pWscCtrl, FALSE);
pWscCtrl->bTriggerByNFC = TRUE;
pWscCtrl->NfcModel = MODEL_PASSWORD_TOKEN;
}
}
else
{
Set_NfcPasswdToken_Proc(pAd, "1");
}
break;
/* New type for Handover */
case TYPE_PASSWDHO_S:
DBGPRINT(RT_DEBUG_TRACE, ("TYPE_PASSWDHO_S(=%d)\n", pNfcCmdInfo->type));
if (bSetFromNfc)
{
if (pNfcCmdInfo->data_len != 1)
{
/*
Receive Passwd from NFC daemon. "So far" no this case.
Due to AP always as Registrar in handover procedure,
AP only receive "Handover Request Message".
*/
NfcProcessPasswdTV(pAd, &pNfcCmdInfo->data[0], pNfcCmdInfo->data_len, pWscCtrl, TRUE);
WscGetConfWithoutTrigger(pAd, pWscCtrl, FALSE);
pWscCtrl->bTriggerByNFC = TRUE;
pWscCtrl->NfcModel = MODEL_HANDOVER; /* 2 */
}
}
else
{
Set_NfcPasswdToken_Proc(pAd, "2");
}
break;
case TYPE_PASSWDHO_R:
DBGPRINT(RT_DEBUG_TRACE, ("TYPE_PASSWDHO_R(=%d)\n", pNfcCmdInfo->type));
if (bSetFromNfc)
{
if (pNfcCmdInfo->data_len != 1)
{
/*
Receive Passwd from NFC daemon.
*/
NfcProcessPasswdTV(pAd, &pNfcCmdInfo->data[0], pNfcCmdInfo->data_len, pWscCtrl, TRUE);
WscGetConfWithoutTrigger(pAd, pWscCtrl, FALSE);
pWscCtrl->bTriggerByNFC = TRUE;
pWscCtrl->NfcModel = MODEL_HANDOVER; /* 2 */
}
}
else
{
/*
"So far" no this case.
Due to AP always as Registrar in handover procedure,
AP only send "Handover Select Message".
*/
Set_NfcPasswdToken_Proc(pAd, "3");
}
break;
case TYPE_NFC_STATUS:
DBGPRINT(RT_DEBUG_TRACE, ("TYPE_NFC_STATUS(=%d): NFC Status = %d\n", pNfcCmdInfo->type, pNfcCmdInfo->data[0]));
pWscCtrl->NfcStatus = pNfcCmdInfo->data[0];
break;
case TYPE_WIFI_RADIO_STATUS:
DBGPRINT(RT_DEBUG_TRACE, ("TYPE_WIFI_RADIO_STATUS(=%d)\n", pNfcCmdInfo->type));
if (bSetFromNfc)
{
if (pNfcCmdInfo->data[0] == 1)
MlmeRadioOn(pAd);
else
MlmeRadioOff(pAd);
}
else
{
UCHAR RadioStatus = 0;
if (RTMP_TEST_FLAG(pAd, fRTMP_ADAPTER_RADIO_OFF))
RadioStatus = 0;
else
RadioStatus = 1;
NfcCommand(pAd, 0x01, TYPE_WIFI_RADIO_STATUS, 1, &RadioStatus);
}
break;
default:
DBGPRINT(RT_DEBUG_TRACE, ("Unknow type(=%d)\n", pNfcCmdInfo->type));
break;
}
os_free_mem(NULL, pNfcCmdInfo);
}
DBGPRINT(RT_DEBUG_TRACE, ("<==== %s\n", __FUNCTION__));
return;
}
INT Set_NfcStatus_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
UCHAR data = 0;
/*
Action: b¡¦<7:6>: 0x00 ¡V Request, 0x01 ¡V Notify
b¡¦<5:0>: 0x00 ¡V Get, 0x01 - Set
*/
UCHAR action = 1, type = TYPE_NFC_STATUS; /* 5 - NFC Status */
if (simple_strtol(arg, 0, 10) != 0)
data = 1;
data = (UCHAR)simple_strtol(arg, 0, 10);
DBGPRINT(RT_DEBUG_TRACE, ("%s: Set NFC Status(=%d)\n", __FUNCTION__, data));
NfcCommand(pAd, action, type, 1, &data);
return TRUE;
}
INT Set_NfcPasswdToken_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
PWSC_CTRL pWscCtrl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl;
PUCHAR pBuf = NULL;
USHORT BufLen = 0;
UCHAR action = 1, type = TYPE_PASSWORD;
UCHAR val=0;
BOOLEAN bHandover=FALSE;
/*
Action: b¡¦<7:6>: 0x00 ¡V Request, 0x01 ¡V Notify
b¡¦<5:0>: 0x00 ¡V Get, 0x01 - Set
*/
val = (UCHAR)simple_strtol(arg, 0, 10);
if (val == 1) /* Password Token */
{
bHandover = FALSE;
type = TYPE_PASSWORD;
}
else if (val == 2) /* Handover Select */
{
bHandover = TRUE;
type = TYPE_PASSWDHO_S;
}
else if (val == 3) /* Handover Request */
{
bHandover = TRUE;
type = TYPE_PASSWDHO_R;
}
os_alloc_mem(pAd, (UCHAR **)&pBuf, (NFC_WSC_TLV_SIZE*sizeof(UCHAR)));
if (pBuf == NULL)
{
return FALSE;
}
DBGPRINT(RT_DEBUG_TRACE, ("%s: NfcBuildOOBDevPasswdTLV value(=%d) type(=%d)\n", __FUNCTION__,val, type));
NfcBuildOOBDevPasswdTLV(pAd, pWscCtrl, type, pBuf, &BufLen);
if (pBuf && (BufLen != 0))
{
pWscCtrl->bTriggerByNFC = TRUE;
if (type ==TYPE_PASSWORD)
pWscCtrl->NfcModel = MODEL_PASSWORD_TOKEN;
else
pWscCtrl->NfcModel = MODEL_HANDOVER;
DBGPRINT(RT_DEBUG_TRACE, ("%s: NfcBuildOOBDevPasswdTLV NfcModel(=%d)\n", __FUNCTION__,pWscCtrl->NfcModel));
NfcCommand(pAd, action, type, BufLen, pBuf);
os_free_mem(NULL, pBuf);
}
return TRUE;
}
INT Set_NfcConfigurationToken_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
PWSC_CTRL pWscCtrl = &pAd->ApCfg.MBSSID[pObj->ioctl_if].WscControl;
PUCHAR pBuf = NULL;
USHORT BufLen = 0;
/*
Action: b¡¦<7:6>: 0x00 ¡V Request, 0x01 ¡V Notify
b¡¦<5:0>: 0x00 ¡V Get, 0x01 - Set
*/
UCHAR action = 1, type = TYPE_CONFIGURATION;
os_alloc_mem(pAd, (UCHAR **)&pBuf, (NFC_WSC_TLV_SIZE*sizeof(UCHAR)));
if (pBuf == NULL)
{
return FALSE;
}
NfcBuildWscProfileTLV(pAd, pWscCtrl, pBuf, &BufLen);
if (pBuf && (BufLen != 0))
{
NfcCommand(pAd, action, type, BufLen, pBuf);
os_free_mem(NULL, pBuf);
}
if ((pAd->OpMode == OPMODE_AP) && (pWscCtrl->WscConfStatus == WSC_SCSTATE_UNCONFIGURED))
{
pWscCtrl->WscConfStatus = WSC_SCSTATE_CONFIGURED;
WscBuildBeaconIE(pAd, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, 0, NULL, 0,AP_MODE);
WscBuildProbeRespIE(pAd, WSC_MSGTYPE_AP_WLAN_MGR, WSC_SCSTATE_CONFIGURED, FALSE, 0, 0, 0, NULL, 0,AP_MODE);
APUpdateAllBeaconFrame(pAd);
}
if (pWscCtrl->WscUpdatePortCfgTimerRunning)
{
BOOLEAN bCancel;
RTMPCancelTimer(&pWscCtrl->WscUpdatePortCfgTimer, &bCancel);
}
else
pWscCtrl->WscUpdatePortCfgTimerRunning = TRUE;
RTMPSetTimer(&pWscCtrl->WscUpdatePortCfgTimer, 1000);
return TRUE;
}
INT Get_NfcStatus_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
UCHAR data = 0;
/*
Action: b¡¦<7:6>: 0x0 ¡V To NFC, 0x1 ¡V From NFC
b¡¦<5:0>: 0x0 ¡V Get, 0x01 - Set
*/
UCHAR action = 0, type = TYPE_NFC_STATUS; /* 5 - NFC Status */
NfcCommand(pAd, action, type, 0, NULL);
return TRUE;
}
/*
NfcPasswdCompute:
1 - use hex device passwd to calculate PSK1 & PSK2.
2 - the device password is expressed in hexadecimal using ASCII characters (two characters per octet, uppercase letters only) to caculate PSK1 & PSK2.
*/
INT Set_DoWpsByNFC_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
UCHAR apidx = pObj->ioctl_if, mac_addr[MAC_ADDR_LEN];
BOOLEAN bFromApCli = FALSE;
PWSC_CTRL pWscCtrl;
UINT32 val = 0;
pWscCtrl = &pAd->ApCfg.MBSSID[apidx].WscControl;
val = simple_strtol(arg, 0, 10);
if (val == 0)
pWscCtrl->bTriggerByNFC = FALSE;
else
{
pWscCtrl->bTriggerByNFC = TRUE;
pWscCtrl->NfcPasswdCaculate = val;
}
DBGPRINT(RT_DEBUG_TRACE, ("%s : bTriggerByNFC=%d, NfcPasswdCaculate = %d\n",
__FUNCTION__, pWscCtrl->bTriggerByNFC, pWscCtrl->NfcPasswdCaculate));
return TRUE;
}
INT Set_NfcRegenPK_Proc(RTMP_ADAPTER *pAd, RTMP_STRING *arg)
{
POS_COOKIE pObj = (POS_COOKIE) pAd->OS_Cookie;
UCHAR apidx = pObj->ioctl_if, mac_addr[MAC_ADDR_LEN];
BOOLEAN bFromApCli = FALSE;
PWSC_CTRL pWscCtrl;
UINT32 val = 0;
pWscCtrl = &pAd->ApCfg.MBSSID[apidx].WscControl;
val = simple_strtol(arg, 0, 10);
if (val == 1)
pWscCtrl->bRegenPublicKey = 1;
else
pWscCtrl->bRegenPublicKey = 0;
DBGPRINT(RT_DEBUG_TRACE, ("%s : bRegenPublicKey=%d, \n",
__FUNCTION__, pWscCtrl->bRegenPublicKey));
}
#endif /* WSC_NFC_SUPPORT */