⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 car6koid.cpp

📁 Atheros Communications AR6001 WLAN Driver for SDIO installation Read Me March 26,2007 (based on
💻 CPP
📖 第 1 页 / 共 5 页
字号:

/*
 * The target combines association request and response
 * into a single byte stream and notifies the same in 
 * connect_event. assocReqLen is the length in bytes of
 * association request and assocRespLen is the length in
 * bytes of association response. There is one glitch 
 * though. The association request that is passed by the
 * target contains only the Variable IEs and the fixed
 * IEs like listen Interval and AP address are passed
 * as arguments to the connect_event. However the association
 * response passed to the host contains the full 802.11
 * frame as seen on the wire. That is, in essence the request
 * and response parsing will not be symmetrical. 
 * One pending kludge to be fixed - WZC requires Capabilities
 * IE for both request and response as it is not returned 
 * in requests, it is hardcoded as 0x3104
 */
NDIS_STATUS
CAR6KMini::Get802_11AssociationInformation(
	OUT NDIS_802_11_ASSOCIATION_INFORMATION *pAssocInfo,
	IN  ULONG                                cbBuffer, 
	OUT ULONG                               *pcbNeeded)
{
	PBYTE  ptr;

	if (m_AssocReqLen == 0 && m_AssocRespLen == 0) {
		*pcbNeeded = 0;
		return NDIS_STATUS_SUCCESS;
	}
	*pcbNeeded = m_AssocReqLen + m_AssocRespLen + sizeof(*pAssocInfo);

	if (cbBuffer < *pcbNeeded) {
		return NDIS_STATUS_INVALID_LENGTH;
	}

	memcpy(pAssocInfo->RequestFixedIEs.CurrentAPAddress,
		m_PeerBSSID, ETHERNET_MAC_ADDRESS_LENGTH);

	pAssocInfo->AvailableRequestFixedIEs = 
		NDIS_802_11_AI_REQFI_CAPABILITIES | 
		NDIS_802_11_AI_REQFI_LISTENINTERVAL |
		NDIS_802_11_AI_REQFI_CURRENTAPADDRESS;

	pAssocInfo->OffsetRequestIEs = sizeof(*pAssocInfo);
	pAssocInfo->RequestIELength = m_AssocReqLen - 4;
	ptr = m_pAssocInfo + m_BeaconIeLen;
	pAssocInfo->RequestFixedIEs.Capabilities = ((*(ptr + 1)) << 8) | *ptr;
	ptr += 2;
	pAssocInfo->RequestFixedIEs.ListenInterval = ((*(ptr + 1)) << 8) | *ptr;
	ptr += 2;
	memcpy((PBYTE)pAssocInfo + pAssocInfo->OffsetRequestIEs, ptr, 
		pAssocInfo->RequestIELength);

	
	pAssocInfo->AvailableResponseFixedIEs = 
		NDIS_802_11_AI_RESFI_CAPABILITIES |
		NDIS_802_11_AI_RESFI_STATUSCODE   |
		NDIS_802_11_AI_RESFI_ASSOCIATIONID;

	pAssocInfo->OffsetResponseIEs = sizeof(*pAssocInfo) + 
						pAssocInfo->RequestIELength;
#ifndef AR6K_FIRMWARE_1_0
	pAssocInfo->ResponseIELength = m_AssocRespLen - 6;
	ptr = m_pAssocInfo + m_BeaconIeLen + m_AssocReqLen;
#else
	pAssocInfo->ResponseIELength = m_AssocRespLen - 
					(sizeof(struct ieee80211_frame) + 6);
	ptr = m_pAssocInfo + m_AssocReqLen + sizeof(struct ieee80211_frame);
#endif
	pAssocInfo->ResponseFixedIEs.Capabilities = ((*(ptr + 1)) << 8) | *ptr;
	ptr += 2;
	pAssocInfo->ResponseFixedIEs.StatusCode = ((*(ptr + 1)) << 8) | *ptr;
	ptr += 2;
	pAssocInfo->ResponseFixedIEs.AssociationId = ((*(ptr + 1)) << 8) | *ptr;
	ptr += 2;
	memcpy((PBYTE)pAssocInfo + pAssocInfo->OffsetResponseIEs, ptr, 
		pAssocInfo->ResponseIELength);

	pAssocInfo->Length = sizeof(*pAssocInfo);

	return NDIS_STATUS_SUCCESS;
}

#ifdef SUPPORT_WPA2
NDIS_STATUS
CAR6KMini::Get802_11PMKID(OUT NDIS_802_11_PMKID *pPMKID, 
						  IN  ULONG              cbBuffer, 
						  OUT ULONG             *pcbNeeded)
{
	unsigned int i = 0;

	if (m_AuthenticationMode != Ndis802_11AuthModeWPA2) {
		return NDIS_STATUS_INVALID_DATA;
	}

	if (m_pPMKID == NULL) {
		return NDIS_STATUS_INVALID_DATA;
	}

    *pcbNeeded = m_pPMKID->Length;

	if (cbBuffer < m_pPMKID->Length) {
		return NDIS_STATUS_INVALID_LENGTH;
	}

    pPMKID->Length = m_pPMKID->Length;
	pPMKID->BSSIDInfoCount = m_pPMKID->BSSIDInfoCount;

	for (i=0; i<pPMKID->BSSIDInfoCount; i++) {
		memcpy(pPMKID->BSSIDInfo[i].BSSID,
			m_pPMKID->BSSIDInfo[i].BSSID, 6);
		memcpy(pPMKID->BSSIDInfo[i].PMKID,
			m_pPMKID->BSSIDInfo[i].PMKID, 16);
	}

	return NDIS_STATUS_SUCCESS;
}

NDIS_STATUS
CAR6KMini::Get802_11Capability(OUT NDIS_802_11_CAPABILITY *pCap, 
						   IN ULONG                   cbBuffer, 
						   OUT ULONG                  *pcbNeeded)
{
    ULONG i = 0;
    ULONG lenNeeded;

	lenNeeded = sizeof(pCap->Version) + sizeof(pCap->NoOfPMKIDs) +
                sizeof(pCap->NoOfAuthEncryptPairsSupported) + sizeof(pCap->Length) +
		        (10 * sizeof(NDIS_802_11_AUTHENTICATION_ENCRYPTION));

    *pcbNeeded = lenNeeded;

    if (cbBuffer < lenNeeded) {
	    return NDIS_STATUS_INVALID_LENGTH;
    }

	pCap->Version = 2;
	pCap->NoOfPMKIDs = 3; //no of PMKIDs that can be cached, min of 3 and max of 16.
	pCap->NoOfAuthEncryptPairsSupported = 10; //excluding WEP shared and WPA-None
	pCap->Length = lenNeeded; 
	for (i = 0; i < 10; i++) {
		pCap->AuthenticationEncryptionSupported[i].AuthModeSupported = 
			g_WPA2AuthEncryptPairSupported[i].AuthModeSupported;
		pCap->AuthenticationEncryptionSupported[i].EncryptStatusSupported = 
			g_WPA2AuthEncryptPairSupported[i].EncryptStatusSupported;
	}

	return NDIS_STATUS_SUCCESS;
}
#endif //SUPPORT_WPA2

// AR6K 802.11 OID Set Handlers

NDIS_STATUS
CAR6KMini::Set802_11AssociatedAPBSSID(
	IN NDIS_802_11_MAC_ADDRESS *BSSID)
{
	memcpy(m_DesiredAPBSSID, BSSID, sizeof(NDIS_802_11_MAC_ADDRESS));

	// Setting the desired BSSID results in the following actions:
	//  o If the device is associated with an AP that has the same BSSID, the device must reassociate with the AP
	//  o If the device is associated with a different AP, then it must dissasociate from it then associate with the desired AP.
	//  o If the device is not associated, then it must attempt to associate to the specified BSSID
	//
	// The desired BSSID is cleared by setting it to MAC address 0xFFFFFFFFFFFF. When set to that broadcast address,
	// the device may associate with any AP that matches the desired SSID.
	//
	return NDIS_STATUS_SUCCESS;
}

bool
IsBroadcastAddress(
	IN PBYTE pMACAddress)
//
//  Return true if the MAC address is all 1's (i.e. FF FF FF FF FF FF)
//
{
	bool IsBroadcast = true;

	for (UINT i = 0; i < sizeof(NDIS_802_11_MAC_ADDRESS); i++)
	{
		if (pMACAddress[i] != 0xFF)
		{
			IsBroadcast = false;
			break;
		}
	}

	return IsBroadcast;
}

NDIS_STATUS
CAR6KMini::SendWMIConnectCommand(
	IN NDIS_802_11_SSID *SSID)
//
//  Request that the Wireless Module associate with the specified SSID.
//
{
	NDIS_STATUS  Status = NDIS_STATUS_SUCCESS;
	A_STATUS     wmiStatus;
	NETWORK_TYPE wmiNetworkType = m_InfrastructureMode == Ndis802_11Infrastructure ? INFRA_NETWORK : ADHOC_NETWORK;
	DOT11_AUTH_MODE wmiDot11AuthMode = OPEN_AUTH;
	AUTH_MODE    wmiAuthMode = NONE_AUTH;
	BYTE        *pAPBSSID;
	CRYPTO_TYPE keyType = NONE_CRYPT;
	BYTE KeyIndex = 0;
        A_UINT16 channel = (m_InfrastructureMode == Ndis802_11IBSS) ? (A_UINT16)(m_Config.ibssChannel/1000) : 0;

	//
	// CONNECT commands can only be sent in the DISCONNECTED state.
	//
	ASSERT(false == m_Connected);
	ASSERT(false == m_ConnectInProgress);


	switch(m_AuthenticationMode)
	{
	case Ndis802_11AuthModeOpen:
		wmiDot11AuthMode = OPEN_AUTH;
		break;

	case Ndis802_11AuthModeShared:
		wmiDot11AuthMode = SHARED_AUTH;
		break;

	case Ndis802_11AuthModeWPA:
		wmiAuthMode = WPA_AUTH;
		break;

	case Ndis802_11AuthModeWPAPSK:
		wmiAuthMode = WPA_PSK_AUTH;
		break;

	case Ndis802_11AuthModeWPA2PSK:
		wmiAuthMode = WPA2_PSK_AUTH;
		break;
		
	case Ndis802_11AuthModeWPA2:
		wmiAuthMode = WPA2_AUTH;
		break;

	default:
		break;
	}
	if (m_AuthAlg == 0x04) { 
		wmiDot11AuthMode = LEAP_AUTH;
	}


	switch (m_EncryptionStatus)
	{
	case Ndis802_11WEPEnabled:
		m_PairwiseCryptoType = WEP_CRYPT;
		m_GrpwiseCryptoType = WEP_CRYPT;
		break;

	case Ndis802_11WEPDisabled:
		m_PairwiseCryptoType = NONE_CRYPT;
		m_GrpwiseCryptoType = NONE_CRYPT;
		break;

	case Ndis802_11Encryption2Enabled:
		m_PairwiseCryptoType = TKIP_CRYPT;
		m_GrpwiseCryptoType = Encryption2GrpwiseCryptoTable[m_GrpwiseCryptoIndex];
		m_GrpwiseCryptoIndex = (m_GrpwiseCryptoIndex++) % ENCRYPT2_GRPWISE_CRYPTOINDEX_MAX;

		break;

	case Ndis802_11Encryption3Enabled:
		m_PairwiseCryptoType = AES_CRYPT;
		m_GrpwiseCryptoType = Encryption3GrpwiseCryptoTable[m_GrpwiseCryptoIndex];
		m_GrpwiseCryptoIndex = (m_GrpwiseCryptoIndex++) % ENCRYPT3_GRPWISE_CRYPTOINDEX_MAX;
				
		break;

	default:
		break;
	}

	pAPBSSID = NULL;
	if (!IsBroadcastAddress(m_DesiredAPBSSID))
		pAPBSSID = m_DesiredAPBSSID;

	NDIS_DEBUG_PRINTF(ATH_LOG_INF, "Connect command from Supplicant\n");


	if (m_WMIBssFilter !=  ALL_BSS_FILTER) { 
	    wmiStatus = wmi_bssfilter_cmd((struct wmi_t *)m_pWMI, ALL_BSS_FILTER);
	    if (wmiStatus == A_OK) {
		    m_WMIBssFilter = ALL_BSS_FILTER;
	    } else {
		    return NDIS_STATUS_FAILURE;
		}
	}

	//Add the keys to the NIC, before issuing the connect cmd.
	//Add the keys here only if the Auth mode is either SharedAuth or AutoSwitch. Only for
	//Shared Auth the WEP keys are plumbed before the connection.

	if (m_AuthenticationMode == Ndis802_11AuthModeShared ||
		m_AuthenticationMode == Ndis802_11AuthModeAutoSwitch ) {

		for (KeyIndex = 0; KeyIndex < 4 ; KeyIndex++ ) {

			if ( m_cbKey[KeyIndex] != 0 ) {

				if( (m_KeyUsage[KeyIndex] & GROUP_USAGE) == GROUP_USAGE )
				{
					keyType = m_GrpwiseCryptoType;
				} else {

					keyType = m_PairwiseCryptoType;
				}

				wmiStatus = wmi_addKey_cmd((wmi_t *)m_pWMI,
				       (A_UINT8)KeyIndex,
				       WEP_CRYPT, // Only for WEP the keys are added before connect
				       m_KeyUsage[KeyIndex],
				       (A_UINT8)m_cbKey[KeyIndex],
				       (A_UINT8*)&m_KeyRSC[KeyIndex],
				       m_Key[KeyIndex]);

				if (wmiStatus != A_OK) {
				    NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - wmi_addKey_cmd failed = %u\n", wmiStatus);
					return NDIS_STATUS_FAILURE;
				} 
			}
		}
	}

	/* Set the Listen Interval to 1000TUs. This value will be indicated to the
	 * AP in the conn. request. Later set it back locally at the STA to 100/1000 TUs depending on the
	 * power mode.
	 */
	//Increase the listen interval to 1000 TUs to ensure max buffering capacity at the AP.
	
	wmiStatus = wmi_listeninterval_cmd((struct wmi_t *)m_pWMI, 
			MAX_LISTEN_INTERVAL, 0 );

	if (wmiStatus != A_OK) {
	    NDIS_DEBUG_PRINTF(ATH_LOG_ERR,"AR6K: ERROR - wmi_listeninterval_cmd failed = %u\n", wmiStatus);
		return NDIS_STATUS_FAILURE;
	}
	
	wmiStatus = wmi_connect_cmd((wmi_t *)m_pWMI, wmiNetworkType, 
				wmiDot11AuthMode, wmiAuthMode, 
				m_PairwiseCryptoType, 0, 
				m_GrpwiseCryptoType, 0,
				m_SSID.SsidLength, m_SSID.Ssid, 
				pAPBSSID, channel);
	
	if (wmiStatus != A_OK) {
	    NDIS_DEBUG_PRINTF(ATH_LOG_ERR,"AR6K: ERROR - wmi_connect_cmd failed = %u\n", wmiStatus);
		Status = NDIS_STATUS_FAILURE;
    } else {
		m_ConnectInProgress = true;
	}

	return Status;
}

NDIS_STATUS
CAR6KMini::SendWMIDisconnectCommand()
//
//  Request that the Wireless Module disassociate from the current wireless
//  network. This request may be issued in any state. It will cancel an ongoing
//  CONNECT command if one is in progress. A DISCONNECTED_EVENT will always be
//  generated, even if the current state is DISCONNECTED.
//
{
	NDIS_STATUS  Status = NDIS_STATUS_SUCCESS;
	A_STATUS     wmiStatus;

	wmiStatus = wmi_disconnect_cmd((wmi_t *)m_pWMI);
	NDIS_DEBUG_PRINTF(ATH_LOG_INF, "Disconnect from supplicant\n");

	if (wmiStatus != A_OK) {
	    NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - wmi_disconnect_cmd failed = %u\n", wmiStatus);
		Status = NDIS_STATUS_FAILURE;
    }

	return Status;
}


NDIS_STATUS
CAR6KMini::Set802_11SSID(
	IN NDIS_802_11_SSID *SSID)
//
//  This request informs the driver of the SSID to associate to. If the first
//  character of the SSID string is zero, then it can associate with any SSID.
//  If the SSID is invalid (contains non printable ASCII characters), then the
//  adapter should not associate with any SSID.
//
{
	NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
	A_STATUS wmiStatus;
	NDIS_802_11_SSID *lSSID; 
		
	if (!m_WMIReady) {
		Status = NDIS_STATUS_ADAPTER_NOT_READY;
		goto done;
	}

	if (m_RadioDisabled) {
		m_RadioDisabled = FALSE;
		configRegistryParameters();
		configTargetParams();
		wmiStatus = wmi_startscan_cmd((wmi_t *)m_pWMI,WMI_LONG_SCAN);
		if (wmiStatus != A_OK)
			NDIS_DEBUG_PRINTF(ATH_LOG_ERR, "AR6K: ERROR - wmi_startscan_cmd failed = %u\n", wmiStatus);
	}

	if (SSID->SsidLength > 32)
	{
		// Bad length
		Status = NDIS_STATUS_INVALID_DATA;
		goto done;
	}

	// SSID may be NULL to connect to any available SSID
	if (SSID->SsidLength == 0) {
		ULONG dwSize = 2048;
		ULONG NoOfItems,ssidLength;
		ULONG *pcbNeeded=(ULONG *)malloc(sizeof(ULONG));
		NDIS_802_11_BSSID_LIST_EX *pBSSIDListEx = (NDIS_802_11_BSSID_LIST_EX *)malloc(dwSize);
		this->Get802_11BSSIDList(pBSSIDListEx,dwSize,pcbNeeded);
		if(pBSSIDListEx) {
			NoOfItems = pBSSIDListEx->NumberOfItems;
			NDIS_WLAN_BSSID_EX *pBSSID = (NDIS_WLAN_BSSID_EX *) &pBSSIDListEx->Bssid[0];
			while (NoOfItems) {
				if (pBSSID->Privacy) {
					pBSSID = (NDIS_WLAN_BSSID_EX *)((PBYTE)pBSSID + pBSSID->Length);
					NoOfItems--;
				} else {
					ssidLength=pBSSID->Ssid.SsidLength;
					if(ssidLength) {
						lSSID=&pBSSID->Ssid;
						m_AuthenticationMode=Ndis802_11AuthModeOpen;
						m_EncryptionStatus=Ndis802_11WEPDisabled;
						break;	
					} else {
						pBSSID = (NDIS_WLAN_BSSID_EX *)((PBYTE)pBSSID + pBSSID->Length);
						NoOfItems--;
					}
				} 
			}
		free(pBSSIDListEx);
		}
	} 
	else {
		lSSID=SSID;
	}

	m_WantToBeConnected = SSIDIsValid(SSID);
	if (false == m_WantToBeConnected)
	{
		m_SSID = *lSSID;

		// We want to abort any connection attempt in progress, and
		// dissassociate from any SSID to which we are current associated.
		if (m_ConnectInProgress || m_Connected)
		{
			Status = SendWMIDisconnectCommand();
		}
	}
	else
	{
		// The set SSID maybe same as the one we are already connected or different.
		// In any case we issue a disconnect if we are already connected. This is because
		// there may be a change in the Conn. profile (such as encryption key) that warrants
		// a disconnect & reconnect.

		// We want to associate to the specified SSID
		if (lSSID->SsidLength == m_SSID.SsidLength
		&&  0 == memcmp(lSSID->Ssid, m_SSID.Ssid, m_SSID.SsidLength))
		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -