/************************************************************************
 *                        buildDisconnTemplate								*
 ************************************************************************
DESCRIPTION: This function build a Death/Disassoc template to set to the HAL 
				when joining an infrastructure network
				performs the following:
				-	Build a template & set the template len, the template type is set in the site mgr
                                                                                                   
INPUT:      pSiteMgr	-	Handle to site manager	
			pTemplate	-	Pointer to the template structure		


OUTPUT:		


RETURN:     TI_OK

************************************************************************/
TI_STATUS buildDisconnTemplate(siteMgr_t *pSiteMgr, TSetTemplate *pTemplate)
{
	paramInfo_t			param;
	TI_UINT32				size;
	disconnTemplate_t	*pBuffer = (disconnTemplate_t	*)pTemplate->ptr;
	siteEntry_t			*pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite;
	TI_UINT16				fc;

	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(disconnTemplate_t));

	/*
	 * Header First
	 */
	/* Set destination address */
	MAC_COPY (pBuffer->hdr.DA, pPrimarySite->bssid);  

	/* Set BSSID address */
	MAC_COPY (pBuffer->hdr.BSSID, pPrimarySite->bssid);  

	/* Build Source address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY (pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress);  
	
	fc = DOT11_FC_DISASSOC; /* will be change by firmware to DOT11_FC_DEAUTH if needed */

	COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc); /* copy with endianess handling. */

	pBuffer->disconnReason = 0; /* filled by firmware */
	
	size = sizeof(disconnTemplate_t);

	pTemplate->len = size;
	
	return TI_OK;
}
示例#2
0
/************************************************************************
 *                        buildArpRspTemplate							*
 ************************************************************************
DESCRIPTION: This function builds an ARP Response template to set to 
			 the HAL when joining an infrastructure network.

             The function's steps:
             - It builds the template & set the template len. 
             - If QoS is inactive, it discards the QoS Control Field.
             ** The template type is set in the site mgr.
                                           
INPUT:       pSiteMgr  - Handle to site manager.
			 pTemplate - Pointer to the template structure.

OUTPUT:		

RETURN:     TI_OK

************************************************************************/
TI_STATUS buildArpRspTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate,
			      TIpAddr staIp)
{
	siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite;
	ArpRspTemplate_t *pBuffer = (ArpRspTemplate_t *) pTemplate->ptr;
	TI_UINT8 *ptr = (TI_UINT8 *) pBuffer;

	paramInfo_t param;	/* To get Site and QoS params */
	TI_UINT16 fc;		/* Frame Control field in MAC header */
	TI_UINT16 macAddrItr;
	TI_BOOL privacyInvoked;
	TI_UINT8 encryptionFieldSize, copyPayloadOffset, lenToCopy;

	/* Reset the buffer */
	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(ArpRspTemplate_t));

	/* Turn on the To_DS bit in the Frame Control field */
	fc = (1 << DOT11_FC_TO_DS_SHIFT);
	
	    /* Set MAC header address fields:
	       -----------------------------
	       Since To_DS is on and From_DS is off the address meaning is as follows:
	       Address1 - BSSID
	       Address2 - Source Address
	       Address3 - Destination Address
	       Address4 - Not present */
	    /* - Set BSSID */
	    if (pPrimarySite) {
		MAC_COPY(pBuffer->hdr.address1, pPrimarySite->bssid);
	} else {
		TRACE0(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION,
		       "No Primary site so cannot fill QosNullData template.\n");
	}
	/* - Set Source Address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY(pBuffer->hdr.address2, param.content.ctrlDataDeviceMacAddress);
	/* - Set Destination Address: ARP response should be sent with broadcast DA - Set accordingly */
	for (macAddrItr = 0; macAddrItr < MAC_ADDR_LEN; macAddrItr++) {
		pBuffer->hdr.address3[macAddrItr] = 0xFF;
	}

	pBuffer->LLC.DSAP = 0xaa;
	pBuffer->LLC.SSAP = 0xaa;
	pBuffer->LLC.Control = 0x03;

	/* pBuffer->LLC.Control.OUI these 3 bytes are zeroed already */
	pBuffer->LLC.Type = WLANTOHS((TI_UINT16) 0x806);
	pBuffer->hardType = WLANTOHS((TI_UINT16) 1);
	pBuffer->protType = WLANTOHS((TI_UINT16) 0x800);
	pBuffer->hardSize = 6;
	pBuffer->protSize = 4;
	pBuffer->op = WLANTOHS((TI_UINT16) 2);	/*filled as for ARP-RSP, not for RARP_RSP */

	MAC_COPY(pBuffer->StaMac, pBuffer->hdr.address2);
	IP_COPY(pBuffer->StaIp, staIp);

	pTemplate->len = sizeof(ArpRspTemplate_t);

	/* Get encryption status */
	txCtrlParams_getCurrentEncryptionInfo(pSiteMgr->hTxCtrl,
					      &privacyInvoked,
					      &encryptionFieldSize);

	/* If no encryption is used, encryptionFieldSize has garbage value */
	encryptionFieldSize = privacyInvoked ? encryptionFieldSize : 0;

	/* Set the subtype field of fc with WEP_BIT */
	fc |= (privacyInvoked << DOT11_FC_WEP_SHIFT);

	/* Get QoS type to check if QoS is active */
	param.paramType = QOS_MNGR_ACTIVE_PROTOCOL;
	qosMngr_getParams(pSiteMgr->hQosMngr, &param);

	if (param.content.qosSiteProtocol == QOS_NONE) {	/* QoS is not active */
		copyPayloadOffset =
		    sizeof(pBuffer->hdr.qosControl) +
		    AES_AFTER_HEADER_FIELD_SIZE - encryptionFieldSize;
		/* Set the subtype field of fc with DATA value (non Qos) */
		fc |= DOT11_FC_DATA;
	} else {		/* QoS is active */

		copyPayloadOffset =
		    AES_AFTER_HEADER_FIELD_SIZE - encryptionFieldSize;
		/* Set the subtype field of fc with DATA_QOS */
		fc |= DOT11_FC_DATA_QOS;
	}

	/* Need to copy backward to overwrite security or QoS offset */
	if (copyPayloadOffset > 0) {
		ptr = (TI_UINT8 *) & pBuffer->LLC.DSAP;
		/* Copy back the actual payload without header & security */
		lenToCopy =
		    sizeof(ArpRspTemplate_t) - sizeof(dot11_header_t) -
		    AES_AFTER_HEADER_FIELD_SIZE;

		os_memoryCopy(pSiteMgr->hOs, ptr - copyPayloadOffset, ptr,
			      lenToCopy);
		pTemplate->len -= copyPayloadOffset;
	}

	COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc);	/* copy with endianess handling. */

	return TI_OK;
}
示例#3
0
/************************************************************************
 *                        buildProbeRspTemplate							*
 ************************************************************************
DESCRIPTION: This function build a probe response template to set to the HAL 
				when joining an IBSS network.
				performs the following:
				-	Build a template & set the template len, the template type is set in the site mgr
				-	The template is built based on the chosen site attributes

			NOTE: This function is used to build beacon template too.
			The site manager set the template type (after thos function returns) to beacon or probe response accordingly.
                                                                                                   
INPUT:      pSiteMgr	-	Handle to site manager	
			pTemplate	-	Pointer to the template structure		

OUTPUT:		

RETURN:     TI_OK

************************************************************************/
TI_STATUS buildProbeRspTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate)
{
	paramInfo_t param;
	TI_UINT8 *pBuf;
	probeRspTemplate_t *pBuffer = (probeRspTemplate_t *) pTemplate->ptr;
	siteEntry_t *pPrimarySite = pSiteMgr->pSitesMgmtParams->pPrimarySite;
	TI_INT32 i, j;
	TI_UINT32 size;
	dot11_RATES_t *pDot11Rates;
	dot11_ERP_t *pdot11Erp;
	TI_UINT32 len = 0, ofdmIndex = 0;
	TI_BOOL extRates = TI_FALSE;
	TI_BOOL useProtection, NonErpPresent, barkerPreambleType;
	TCountry *pCountry = NULL;
	TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES];
	TI_UINT32 supportedRateMask, basicRateMask;
	TI_UINT16 headerFC = DOT11_FC_PROBE_RESP;

	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(probeRspTemplate_t));

	/*
	 * Build WLAN Header:
	 * ==================
	 */

	/* Set destination address */
	for (i = 0; i < MAC_ADDR_LEN; i++)
		pBuffer->hdr.DA[i] = 0xFF;

	/* Set BSSID address */
	MAC_COPY(pBuffer->hdr.BSSID, pPrimarySite->bssid);

	/* Build Source address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress);

	COPY_WLAN_WORD(&pBuffer->hdr.fc, &headerFC);

	size = sizeof(dot11_mgmtHeader_t);
	pBuf = (TI_UINT8 *) pBuffer->timeStamp;
	/*
	 * Fixed Fields
	 */
	/* we skip the timestamp field */
	size += TIME_STAMP_LEN;
	pBuf += TIME_STAMP_LEN;

	/* Beacon interval */
	COPY_WLAN_WORD(pBuf, &pPrimarySite->beaconInterval);
	size += FIX_FIELD_LEN;
	pBuf += FIX_FIELD_LEN;

	/* capabilities */
	COPY_WLAN_WORD(pBuf, &pPrimarySite->capabilities);
	size += FIX_FIELD_LEN;
	pBuf += FIX_FIELD_LEN;

	/*
	 * Build Informataion Elements:
	 * ============================
	 */

	/* SSID IE */
	/* It looks like it never happens. Anyway decided to check */
	if (pPrimarySite->ssid.len > MAX_SSID_LEN) {
		TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR,
		       "buildProbeRspTemplate. pPrimarySite->ssid.len=%d exceeds the limit %d\n",
		       pPrimarySite->ssid.len, MAX_SSID_LEN);
		handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION);
		return TI_NOK;
	}
	((dot11_SSID_t *) (pBuf))->hdr[0] = DOT11_SSID_ELE_ID;
	((dot11_SSID_t *) (pBuf))->hdr[1] = pPrimarySite->ssid.len;
	os_memoryCopy(pSiteMgr->hOs, pBuf + sizeof(dot11_eleHdr_t),
		      (void *)pPrimarySite->ssid.str, pPrimarySite->ssid.len);
	size += sizeof(dot11_eleHdr_t) + pPrimarySite->ssid.len;
	pBuf += sizeof(dot11_eleHdr_t) + pPrimarySite->ssid.len;

	/* Rates IE */

	pDot11Rates = (dot11_RATES_t *) pBuf;

	if (pPrimarySite->channel == SPECIAL_BG_CHANNEL) {
		supportedRateMask = rate_GetDrvBitmapForDefaultSupporteSet();
		basicRateMask = rate_GetDrvBitmapForDefaultBasicSet();
	} else {
		supportedRateMask =
		    pSiteMgr->pDesiredParams->siteMgrMatchedSuppRateMask;
		basicRateMask =
		    pSiteMgr->pDesiredParams->siteMgrMatchedBasicRateMask;
	}

	rate_DrvBitmapToNetStr(supportedRateMask, basicRateMask, ratesBuf, &len,
			       &ofdmIndex);

	if (pSiteMgr->siteMgrOperationalMode != DOT11_G_MODE ||
	    pSiteMgr->pDesiredParams->siteMgrUseDraftNum == DRAFT_5_AND_EARLIER
	    || ofdmIndex == len) {
		pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = len;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      ratesBuf, pDot11Rates->hdr[1]);
		size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
	} else {
		pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = ofdmIndex;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      ratesBuf, pDot11Rates->hdr[1]);
		size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		extRates = TI_TRUE;
	}

	/* DS IE */
	((dot11_DS_PARAMS_t *) (pBuf))->hdr[0] = DOT11_DS_PARAMS_ELE_ID;
	((dot11_DS_PARAMS_t *) (pBuf))->hdr[1] = DOT11_DS_PARAMS_ELE_LEN;
	((dot11_DS_PARAMS_t *) (pBuf))->currChannel = pPrimarySite->channel;
	size += sizeof(dot11_eleHdr_t) + DOT11_DS_PARAMS_ELE_LEN;
	pBuf += sizeof(dot11_eleHdr_t) + DOT11_DS_PARAMS_ELE_LEN;

	/* IBSS IE */
	((dot11_IBSS_PARAMS_t *) (pBuf))->hdr[0] = DOT11_IBSS_PARAMS_ELE_ID;
	((dot11_IBSS_PARAMS_t *) (pBuf))->hdr[1] = DOT11_IBSS_PARAMS_ELE_LEN;
	COPY_WLAN_WORD(&((dot11_IBSS_PARAMS_t *) (pBuf))->atimWindow,
		       &pPrimarySite->atimWindow);
	size += sizeof(dot11_eleHdr_t) + DOT11_IBSS_PARAMS_ELE_LEN;
	pBuf += sizeof(dot11_eleHdr_t) + DOT11_IBSS_PARAMS_ELE_LEN;

	/* Country IE */
	param.paramType = REGULATORY_DOMAIN_ENABLED_PARAM;
	regulatoryDomain_getParam(pSiteMgr->hRegulatoryDomain, &param);

	if (param.content.regulatoryDomainEnabled == TI_TRUE) {
		/* get country IE */
		param.paramType = REGULATORY_DOMAIN_COUNTRY_PARAM;
		regulatoryDomain_getParam(pSiteMgr->hRegulatoryDomain, &param);
		pCountry = param.content.pCountry;

		/* Check if a country IE was found */
		if (pCountry != NULL) {
			*pBuf = DOT11_COUNTRY_ELE_ID;
			pBuf++;
			size++;
			*pBuf = (TI_UINT8) (pCountry->len);
			pBuf++;
			size++;

			/* Note: The country structure is not byte-aligned so it is copied as follows to ensure
			   that there are no gaps in the output structure (pBuf). */

			os_memoryCopy(pSiteMgr->hOs, pBuf,
				      &pCountry->countryIE.CountryString,
				      DOT11_COUNTRY_STRING_LEN);
			pBuf += DOT11_COUNTRY_STRING_LEN;
			size += DOT11_COUNTRY_STRING_LEN;

			/* Loop on all tripletChannels. Each item has three fields ('i' counts rows and 'j' counts bytes). */
			for (i = 0, j = 0;
			     j < (pCountry->len - DOT11_COUNTRY_STRING_LEN);
			     i++, j += 3) {
				*(pBuf + j) =
				    pCountry->countryIE.tripletChannels[i].
				    firstChannelNumber;
				*(pBuf + j + 1) =
				    pCountry->countryIE.tripletChannels[i].
				    maxTxPowerLevel;
				*(pBuf + j + 2) =
				    pCountry->countryIE.tripletChannels[i].
				    numberOfChannels;
			}

			pBuf += (pCountry->len - DOT11_COUNTRY_STRING_LEN);
			size += (pCountry->len - DOT11_COUNTRY_STRING_LEN);
		}
	}

	/*ERP IE */
	siteMgr_IsERP_Needed(pSiteMgr, &useProtection, &NonErpPresent,
			     &barkerPreambleType);
	if (useProtection || NonErpPresent || barkerPreambleType) {
		pdot11Erp = (dot11_ERP_t *) pBuf;
		pdot11Erp->hdr[0] = DOT11_ERP_IE_ID;
		pdot11Erp->hdr[1] = 1;
		pdot11Erp->ctrl = 0;
		if (NonErpPresent)
			pdot11Erp->ctrl |= ERP_IE_NON_ERP_PRESENT_MASK;
		if (useProtection)
			pdot11Erp->ctrl |= ERP_IE_USE_PROTECTION_MASK;
		if (barkerPreambleType)
			pdot11Erp->ctrl |= ERP_IE_BARKER_PREAMBLE_MODE_MASK;
		size += pdot11Erp->hdr[1] + sizeof(dot11_eleHdr_t);
		pBuf += pdot11Erp->hdr[1] + sizeof(dot11_eleHdr_t);

	}

	/* Extended supported rates IE */
	if (extRates) {
		pDot11Rates = (dot11_RATES_t *) pBuf;
		pDot11Rates->hdr[0] = DOT11_EXT_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = len - ofdmIndex;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]);
		size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
	}

	/* no need to insert RSN information elements */

	pTemplate->len = size;
	TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION,
	       "Probe response template len = %d\n", size);

	return TI_OK;
}
示例#4
0
/************************************************************************
 *                        buildProbeReqTemplate							*
 ************************************************************************
DESCRIPTION: This function build a probe request template to set to the HAL in the scan process.
				performs the following:
				-	Build a template & set the template len, the template type is set in the site mgr
                                                                                                   
INPUT:      pSiteMgr	-	Handle to site manager	
			pTemplate	-	Pointer to the template structure		
			pSsid		-	Desired SSID

OUTPUT:		

RETURN:     TI_OK

************************************************************************/
TI_STATUS buildProbeReqTemplate(siteMgr_t * pSiteMgr, TSetTemplate * pTemplate,
				TSsid * pSsid, ERadioBand radioBand)
{
	paramInfo_t param;
	char *pBuf;
	int i;
	probeReqTemplate_t *pBuffer = (probeReqTemplate_t *) pTemplate->ptr;
	TI_UINT32 size;
	dot11_RATES_t *pDot11Rates;
	TI_UINT32 len = 0, ofdmIndex = 0;
	TI_UINT32 suppRatesLen, extSuppRatesLen;
	TI_UINT8 ratesBuf[DOT11_MAX_SUPPORTED_RATES];
	TI_UINT8 WSCOuiIe[DOT11_OUI_LEN] = { 0x00, 0x50, 0xf2, 0x04 };
	TI_UINT32 supportedRateMask, basicRateMask;
	TI_UINT16 fc = DOT11_FC_PROBE_REQ;

	os_memoryZero(pSiteMgr->hOs, pBuffer, sizeof(probeReqTemplate_t));

	/*
	 * Header First
	 */
	/* Set destination address */
	for (i = 0; i < MAC_ADDR_LEN; i++)
		pBuffer->hdr.DA[i] = 0xFF;

	/* Set BSSID address */

	for (i = 0; i < MAC_ADDR_LEN; i++)
		pBuffer->hdr.BSSID[i] = 0xFF;

	/* Build Source address */
	param.paramType = CTRL_DATA_MAC_ADDRESS;
	ctrlData_getParam(pSiteMgr->hCtrlData, &param);
	MAC_COPY(pBuffer->hdr.SA, param.content.ctrlDataDeviceMacAddress);

	COPY_WLAN_WORD(&pBuffer->hdr.fc, &fc);	/* copy with endianess handling. */

	size = sizeof(dot11_mgmtHeader_t);
	pBuf = (char *)&(pBuffer->infoElements);

	/*
	 * Informataion elements
	 */
	/* SSID */
	/* It looks like it never happens. Anyway decided to check */
	if (pSsid->len > MAX_SSID_LEN) {
		TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR,
		       "buildProbeReqTemplate. pSsid->len=%d exceeds the limit %d\n",
		       pSsid->len, MAX_SSID_LEN);
		handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION);
		return TI_NOK;
	}
	((dot11_SSID_t *) (pBuf))->hdr[0] = DOT11_SSID_ELE_ID;
	((dot11_SSID_t *) (pBuf))->hdr[1] = pSsid->len;
	os_memoryCopy(pSiteMgr->hOs, pBuf + sizeof(dot11_eleHdr_t),
		      (void *)pSsid->str, pSsid->len);
	size += sizeof(dot11_eleHdr_t) + pSsid->len;
	pBuf += sizeof(dot11_eleHdr_t) + pSsid->len;

	/* Rates */
	pDot11Rates = (dot11_RATES_t *) pBuf;

	/* 
	 * Supported rates in probe request will always use the default rates for BG or A bands,
	 * regardless of the STA desired rates.
	 */
	if (radioBand == RADIO_BAND_2_4_GHZ) {
		/* Basic rates: 1,2,5.5,11 */
		basicRateMask =
		    rate_BasicToDrvBitmap((EBasicRateSet)
					  (pSiteMgr->pDesiredParams->
					   siteMgrRegstryBasicRate
					   [DOT11_G_MODE]), TI_FALSE);
		/* Extended: 6,9,12,18,24,36,48,54 */
		supportedRateMask =
		    rate_SupportedToDrvBitmap((ESupportedRateSet)
					      (pSiteMgr->pDesiredParams->
					       siteMgrRegstrySuppRate
					       [DOT11_G_MODE]), TI_FALSE);
	} else if (radioBand == RADIO_BAND_5_0_GHZ) {	/* Basic rates: 6,12,24 */
		basicRateMask =
		    rate_BasicToDrvBitmap((EBasicRateSet)
					  (pSiteMgr->pDesiredParams->
					   siteMgrRegstryBasicRate
					   [DOT11_A_MODE]), TI_TRUE);
		/* Extended: 9,18,24,36,48,54 */
		supportedRateMask =
		    rate_SupportedToDrvBitmap((ESupportedRateSet)
					      (pSiteMgr->pDesiredParams->
					       siteMgrRegstrySuppRate
					       [DOT11_A_MODE]), TI_TRUE);
	} else {
		TRACE1(pSiteMgr->hReport, REPORT_SEVERITY_ERROR,
		       "buildProbeReqTemplate, radioBand =%d ???\n", radioBand);
		/* Use default and pray for the best */
		/* Basic rates: 1,2,5.5,11 */
		basicRateMask =
		    rate_BasicToDrvBitmap(BASIC_RATE_SET_1_2_5_5_11, TI_FALSE);
		/* Extended: 6,9,12,18,24,36,48,54 */
		supportedRateMask =
		    rate_SupportedToDrvBitmap(SUPPORTED_RATE_SET_UP_TO_54,
					      TI_FALSE);
	}

	rate_DrvBitmapToNetStr(supportedRateMask, basicRateMask, ratesBuf, &len,
			       &ofdmIndex);

	TRACE5(pSiteMgr->hReport, REPORT_SEVERITY_INFORMATION,
	       "buildProbeReqTemplate, supportedRateMask=0x%x, basicRateMask=0x%x, len=%d, ofdmIndex=%d, radioBand =%d\n",
	       supportedRateMask, basicRateMask, len, ofdmIndex, radioBand);

	/* It looks like it never happens. Anyway decided to check */
	if (len > DOT11_MAX_SUPPORTED_RATES) {
		TRACE2(pSiteMgr->hReport, REPORT_SEVERITY_ERROR,
		       "buildProbeReqTemplate. len=%d exceeds the limit %d\n",
		       len, DOT11_MAX_SUPPORTED_RATES);
		handleRunProblem(PROBLEM_BUF_SIZE_VIOLATION);
		return TI_NOK;
	}
	if (radioBand == RADIO_BAND_5_0_GHZ ||
	    pSiteMgr->pDesiredParams->siteMgrUseDraftNum == DRAFT_5_AND_EARLIER
	    || ofdmIndex == len) {
		pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = len;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      ratesBuf, pDot11Rates->hdr[1]);
		size += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		pBuf += pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
	} else {
		pDot11Rates->hdr[0] = DOT11_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = ofdmIndex;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      ratesBuf, pDot11Rates->hdr[1]);
		suppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		pDot11Rates = (dot11_RATES_t *) (pBuf + suppRatesLen);
		pDot11Rates->hdr[0] = DOT11_EXT_SUPPORTED_RATES_ELE_ID;
		pDot11Rates->hdr[1] = len - ofdmIndex;
		os_memoryCopy(pSiteMgr->hOs, (void *)pDot11Rates->rates,
			      &ratesBuf[ofdmIndex], pDot11Rates->hdr[1]);
		extSuppRatesLen = pDot11Rates->hdr[1] + sizeof(dot11_eleHdr_t);
		size += suppRatesLen + extSuppRatesLen;
		pBuf += suppRatesLen + extSuppRatesLen;
	}

	/* add HT capabilities IE */
	StaCap_GetHtCapabilitiesIe(pSiteMgr->hStaCap, (TI_UINT8 *) pBuf, &len);
	size += len;
	pBuf += len;

	/* WiFi Simple Config */
	if (pSiteMgr->includeWSCinProbeReq
	    && (pSiteMgr->siteMgrWSCCurrMode != TIWLN_SIMPLE_CONFIG_OFF)) {
		((dot11_WSC_t *) pBuf)->hdr[0] = DOT11_WSC_PARAM_ELE_ID;
		((dot11_WSC_t *) pBuf)->hdr[1] =
		    pSiteMgr->uWscIeSize + DOT11_OUI_LEN;
		pBuf += sizeof(dot11_eleHdr_t);
		os_memoryCopy(pSiteMgr->hOs, pBuf, &WSCOuiIe, DOT11_OUI_LEN);
		os_memoryCopy(pSiteMgr->hOs,
			      pBuf + DOT11_OUI_LEN,
			      &pSiteMgr->siteMgrWSCProbeReqParams,
			      pSiteMgr->uWscIeSize);
		size +=
		    sizeof(dot11_eleHdr_t) + pSiteMgr->uWscIeSize +
		    DOT11_OUI_LEN;
		pBuf +=
		    sizeof(dot11_eleHdr_t) + pSiteMgr->uWscIeSize +
		    DOT11_OUI_LEN;
	}

	pTemplate->len = size;

	return TI_OK;
}
TI_STATUS mlmeBuilder_sendFrame(TI_HANDLE hMlme, 
							 dot11MgmtSubType_e type, 
							 UINT8 *pDataBuff, 
							 UINT32 dataLen,
							 UINT8	setWepOpt)
{
	TI_STATUS			status;
	mlme_t			*pHandle;
	mem_MSDU_T		*pMsdu;
	paramInfo_t		daParam, saParam;
	dot11_mgmtFrame_t	*pFrame;



	if (hMlme == NULL)
	{
		return NOK;
	}

	pHandle = (mlme_t*)hMlme;


	/* GET NEW MSDU !!! */
	status = wlan_memMngrAllocMSDU(pHandle->hMemMgr, &pMsdu, 
        MAX_MANAGEMENT_FRAME_BODY_LEN + 
            configMgr_getPacketHeaderLength(pHandle->hConfigMgr, NULL, TX_DATA_MGMT_MSDU), 
        MLME_MODULE);
	
    if (status != OK)
		return NOK;
	pFrame = (dot11_mgmtFrame_t*)(pMsdu->firstBDPtr->data + TX_TOTAL_OFFSET_BEFORE_DATA);

	status = mlmeBuilder_buildFrameCtrl(pHandle, type, (UINT16 *)&pFrame->hdr.fc, setWepOpt);
	if (status != OK)
	{
		wlan_memMngrFreeMSDU(pHandle->hMemMgr, pMsdu->handle);
		return NOK;
	}

	daParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM;
	status = ctrlData_getParam(pHandle->hCtrlData, &daParam);
	if (status != OK)
	{
		wlan_memMngrFreeMSDU(pHandle->hMemMgr, pMsdu->handle);
		return NOK;
	}

	/* copy destination mac address */
	MAC_COPY(pHandle->hOs, (&pFrame->hdr.DA), (&daParam.content.ctrlDataCurrentBSSID));

	saParam.paramType = CTRL_DATA_MAC_ADDRESS;
	status = ctrlData_getParam(pHandle->hCtrlData, &saParam);
	if (status != OK)
	{
		wlan_memMngrFreeMSDU(pHandle->hMemMgr, pMsdu->handle);
		return NOK;
	}

	/* copy source mac address */
	MAC_COPY(pHandle->hOs, (&pFrame->hdr.SA), (&saParam.content.ctrlDataCurrentBSSID));

	/* copy BSSID (destination mac address) */
	MAC_COPY(pHandle->hOs, (&pFrame->hdr.BSSID), (&daParam.content.ctrlDataCurrentBSSID));

	if (pDataBuff != NULL)
	{
		os_memoryCopy(pHandle->hOs, (void *)pFrame->body, pDataBuff, dataLen);
	}

	/* Update MSDU parameters */
	pMsdu->headerLen = sizeof(dot11_mgmtHeader_t);
	pMsdu->dataLen = sizeof(dot11_mgmtHeader_t) + dataLen;
	pMsdu->firstBDPtr->dataOffset = TX_TOTAL_OFFSET_BEFORE_DATA;
    pMsdu->firstBDPtr->length = pMsdu->dataLen + pMsdu->firstBDPtr->dataOffset;
 
	/* send the packet to the TX */
	pMsdu->qosTag = 0;
	pMsdu->txFlags |= TX_DATA_MGMT_MSDU;
	
	/* 
     * sign the Disassoc packet 
     * A disassociate indication (if occurs) will be provided via TxComplete
     */
	if (type == DIS_ASSOC)
		pMsdu->txCompleteFlags |= TX_DATA_DISASSOC_SYNC_TRIG;
	
	/* sign the De Auth packet 
     * A De Auth indication (if occurs) will be provided via TxComplete
     */
	if (type == DE_AUTH)
		pMsdu->txCompleteFlags |= TX_DATA_DEAUTH_SYNC_TRIG;

	status = txData_txSendMsdu(pHandle->hTxData, pMsdu);

	return status;
}
示例#6
0
文件: mlme.c 项目: nadlabak/tiwlan
/** 
 * \fn     mlme_assocCapBuild 
 * \brief  builds capabilties of assoc request 
 * 
 * builds capabilties of assoc request  according to the mlme params 
 * 
 * \param  pCtx - pointer to mlme_t
 * \param  cap - <output> pointer to the built capablities

 * \return TI_OK if auth send successfully
 *         TI_NOK otherwise
 * 
 * \sa     mlme_assocRequestMsgBuild 
 */ 
TI_STATUS mlme_assocCapBuild(mlme_t *pCtx, TI_UINT16 *cap)
{
    paramInfo_t         param;
    TI_STATUS           status;
    EDot11Mode          mode;
    TI_UINT32           rateSuppMask, rateBasicMask;
    TI_UINT8            ratesBuf[DOT11_MAX_SUPPORTED_RATES];
    TI_UINT32           len = 0, ofdmIndex = 0;
    TI_BOOL             b11nEnable, bWmeEnable;

    *cap = 0;

    /* Bss type */
    param.paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM;
    status =  ctrlData_getParam(pCtx->hCtrlData, &param);
    if (status == TI_OK)
    {
        if (param.content.ctrlDataCurrentBssType == BSS_INFRASTRUCTURE)
        {
            *cap |= DOT11_CAPS_ESS;
        } else {
            *cap |= DOT11_CAPS_IBSS;
        }
    } else {
        return TI_NOK;
    }

    /* Privacy */
    param.paramType = RSN_ENCRYPTION_STATUS_PARAM;
    status =  rsn_getParam(pCtx->hRsn, &param);
    if (status == TI_OK)
    {
        if (param.content.rsnEncryptionStatus != TWD_CIPHER_NONE)
        {
            *cap |= DOT11_CAPS_PRIVACY;
        }
    } else {
        return TI_NOK;
    }

    /* Preamble */
    param.paramType = SITE_MGR_DESIRED_PREAMBLE_TYPE_PARAM;
    status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
    if (status == TI_OK)
    {
        if (param.content.siteMgrCurrentPreambleType == PREAMBLE_SHORT)
            *cap |= DOT11_CAPS_SHORT_PREAMBLE;
    } else {
        return TI_NOK;
    }

    /* Pbcc */
    param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
    status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
    if (status == TI_OK)
    {
        if(param.content.siteMgrCurrentRateMask.supportedRateMask & DRV_RATE_MASK_22_PBCC)
            *cap |= DOT11_CAPS_PBCC;
    } else {
        return TI_NOK;
    }

    /* Checking if the station supports Spectrum Management (802.11h) */
    param.paramType = REGULATORY_DOMAIN_MANAGEMENT_CAPABILITY_ENABLED_PARAM;
    status =  regulatoryDomain_getParam(pCtx->hRegulatoryDomain, &param);
    if (status == TI_OK )
    {
        if( param.content.spectrumManagementEnabled)
            *cap |= DOT11_SPECTRUM_MANAGEMENT;
    }
    else
    {
        return TI_NOK;
    }

    /* slot time */
    param.paramType = SITE_MGR_OPERATIONAL_MODE_PARAM;
    status = siteMgr_getParam(pCtx->hSiteMgr, &param);
    if(status == TI_OK)
    {
        mode = param.content.siteMgrDot11OperationalMode;
    }
    else
        return TI_NOK;

    if(mode == DOT11_G_MODE)
    {
        /* new requirement: the short slot time should be set only
           if the AP's modulation is OFDM (highest rate) */

        /* get Rates */
        param.paramType = SITE_MGR_CURRENT_RATE_PAIR_PARAM;
        status =  siteMgr_getParam(pCtx->hSiteMgr, &param);
        if (status == TI_OK)
        {
            rateBasicMask = param.content.siteMgrCurrentRateMask.basicRateMask;
            rateSuppMask  = param.content.siteMgrCurrentRateMask.supportedRateMask;
        } else {
            return TI_NOK;
        }

        /* convert the bit map to the rates array */
        rate_DrvBitmapToNetStr (rateSuppMask, rateBasicMask, ratesBuf, &len, &ofdmIndex);

        if(ofdmIndex < len)
            *cap |= DOT11_CAPS_SHORT_SLOT_TIME;

/*
        param.paramType = SITE_MGR_CURRENT_MODULATION_TYPE_PARAM;
        status = siteMgr_getParam(pCtx->hSiteMgr, &param);
        if(param.content.siteMgrCurrentModulationType == DRV_MODULATION_OFDM)
            *cap |= DOT11_CAPS_SHORT_SLOT_TIME;
*/
    }

    /* Primary Site support HT ? */
    param.paramType = SITE_MGR_PRIMARY_SITE_HT_SUPPORT;
    siteMgr_getParam(pCtx->hSiteMgr, &param);

    if (param.content.bPrimarySiteHtSupport == TI_TRUE)
    {
        /* Immediate Block Ack subfield - (is WME on?) AND (is HT Enable?) */
        /* verify 11n_Enable and Chip type */
        StaCap_IsHtEnable (pCtx->hStaCap, &b11nEnable);
        /* verify that WME flag enable */
        qosMngr_GetWmeEnableFlag (pCtx->hQosMngr, &bWmeEnable);

        if ((b11nEnable != TI_FALSE) && (bWmeEnable != TI_FALSE))
        {
            *cap |= DOT11_CAPS_IMMEDIATE_BA;
        }
    }

    return TI_OK;
}
示例#7
0
文件: mlme.c 项目: nadlabak/tiwlan
TI_STATUS mlme_getParam(TI_HANDLE           hMlme,
                        paramInfo_t         *pParam)
{
    mlme_t *pMlme = (mlme_t *)hMlme;

    switch(pParam->paramType)
    {
    case MLME_LEGACY_TYPE_PARAM:
        pParam->content.mlmeLegacyAuthType = pMlme->authInfo.authType;
        break;

    case MLME_CAPABILITY_PARAM:
        pParam->content.mlmeLegacyAuthType = pMlme->legacyAuthType;
        mlme_assocCapBuild(pMlme, &(pParam->content.siteMgrSiteCapability));
        break;

    case MLME_BEACON_RECV:
        pParam->content.siteMgrTiWlanCounters.BeaconsRecv = pMlme->BeaconsCounterPS;
        break;

	case MLME_AUTH_RESPONSE_TIMEOUT_PARAM:
		pParam->content.authResponseTimeout = pMlme->authInfo.timeout;
		break;

	case MLME_AUTH_COUNTERS_PARAM:
		pParam->content.siteMgrTiWlanCounters.AuthRejects = pMlme->authInfo.authRejectCount;
		pParam->content.siteMgrTiWlanCounters.AuthTimeouts = pMlme->authInfo.authTimeoutCount;
		break;

	case MLME_ASSOC_RESPONSE_TIMEOUT_PARAM:
		pParam->content.assocResponseTimeout = pMlme->assocInfo.timeout;
		break;

	case MLME_ASSOCIATION_REQ_PARAM:
        pParam->content.assocReqBuffer.buffer = pMlme->assocInfo.assocReqBuffer;
        pParam->content.assocReqBuffer.bufferSize = pMlme->assocInfo.assocReqLen;
		pParam->content.assocReqBuffer.reAssoc = pMlme->reAssoc;
        break;

	case MLME_ASSOCIATION_RESP_PARAM:
        pParam->content.assocReqBuffer.buffer = pMlme->assocInfo.assocRespBuffer;
        pParam->content.assocReqBuffer.bufferSize = pMlme->assocInfo.assocRespLen;
		pParam->content.assocReqBuffer.reAssoc = pMlme->assocInfo.reAssocResp;
        break;

	case MLME_ASSOC_COUNTERS_PARAM:
        pParam->content.siteMgrTiWlanCounters.AssocRejects = pMlme->assocInfo.assocRejectCount;
        pParam->content.siteMgrTiWlanCounters.AssocTimeouts = pMlme->assocInfo.assocTimeoutCount;
        break;

	case MLME_ASSOCIATION_INFORMATION_PARAM:
       {
           TI_UINT8  reqBuffIEOffset, respBuffIEOffset;
           TI_UINT32 RequestIELength = 0;
           TI_UINT32 ResponseIELength = 0;
           paramInfo_t  *lParam;
           ScanBssType_enum bssType;

           TRACE0(pMlme->hReport, REPORT_SEVERITY_SM, "MLME: DEBUG - Association Information Get:  \n");
           lParam = (paramInfo_t *)os_memoryAlloc(pMlme->hOs, sizeof(paramInfo_t));
           if (!lParam)
           {
               return TI_NOK;
           }

           /* Assoc exists only in Infrastructure */
           lParam->paramType = CTRL_DATA_CURRENT_BSS_TYPE_PARAM;
           ctrlData_getParam(pMlme->hCtrlData, lParam);
           bssType = lParam->content.ctrlDataCurrentBssType;
           os_memoryFree(pMlme->hOs, lParam, sizeof(paramInfo_t));
           if (bssType != BSS_INFRASTRUCTURE)
           {
               TRACE0(pMlme->hReport, REPORT_SEVERITY_ERROR, "Not in Infrastructure BSS, No ASSOC Info for GET ASSOC_ASSOCIATION_INFORMATION_PARAM\n");
               return TI_NOK;
           }

           /* Init the result buffer to 0 */
           os_memoryZero(pMlme->hOs ,&pParam->content, sizeof(OS_802_11_ASSOCIATION_INFORMATION));

           reqBuffIEOffset  = 4;  /* In Assoc request frame IEs are located from byte 4 */
           respBuffIEOffset = 6;  /* In Assoc response frame the IEs are located from byte 6 */

            /* If the last associate was re-associciation, the current AP MAC address */
            /* is placed before the IEs. Copy it to the result parameters.            */
            if (pMlme->reAssoc)
            {
                MAC_COPY (pParam->content.assocAssociationInformation.RequestFixedIEs.CurrentAPAddress,
                          &pMlme->assocInfo.assocReqBuffer[reqBuffIEOffset]);
                reqBuffIEOffset += MAC_ADDR_LEN;
            }

            /* Calculate length of Info elements in assoc request and response frames */
            if(pMlme->assocInfo.assocReqLen > reqBuffIEOffset)
                RequestIELength = pMlme->assocInfo.assocReqLen - reqBuffIEOffset;

            if(pMlme->assocInfo.assocRespLen > respBuffIEOffset)
                ResponseIELength = pMlme->assocInfo.assocRespLen - respBuffIEOffset;

            /* Copy the association request information */
            pParam->content.assocAssociationInformation.Length = sizeof(OS_802_11_ASSOCIATION_INFORMATION);
            pParam->content.assocAssociationInformation.AvailableRequestFixedIEs = OS_802_11_AI_REQFI_CAPABILITIES | OS_802_11_AI_REQFI_LISTENINTERVAL;
            pParam->content.assocAssociationInformation.RequestFixedIEs.Capabilities = *(TI_UINT16*)&(pMlme->assocInfo.assocReqBuffer[0]);
            pParam->content.assocAssociationInformation.RequestFixedIEs.ListenInterval = *(TI_UINT16*)(&pMlme->assocInfo.assocReqBuffer[2]);

            pParam->content.assocAssociationInformation.RequestIELength = RequestIELength;
            pParam->content.assocAssociationInformation.OffsetRequestIEs = 0;
            if (RequestIELength > 0)
            {
                pParam->content.assocAssociationInformation.OffsetRequestIEs = (TI_UINT32)&pMlme->assocInfo.assocReqBuffer[reqBuffIEOffset];
            }
            /* Copy the association response information */
            pParam->content.assocAssociationInformation.AvailableResponseFixedIEs =
                OS_802_11_AI_RESFI_CAPABILITIES | OS_802_11_AI_RESFI_STATUSCODE | OS_802_11_AI_RESFI_ASSOCIATIONID;
            pParam->content.assocAssociationInformation.ResponseFixedIEs.Capabilities = *(TI_UINT16*)&(pMlme->assocInfo.assocRespBuffer[0]);
            pParam->content.assocAssociationInformation.ResponseFixedIEs.StatusCode = *(TI_UINT16*)&(pMlme->assocInfo.assocRespBuffer[2]);
            pParam->content.assocAssociationInformation.ResponseFixedIEs.AssociationId = *(TI_UINT16*)&(pMlme->assocInfo.assocRespBuffer[4]);
            pParam->content.assocAssociationInformation.ResponseIELength = ResponseIELength;
            pParam->content.assocAssociationInformation.OffsetResponseIEs = 0;
            if (ResponseIELength > 0)
            {
                pParam->content.assocAssociationInformation.OffsetResponseIEs = (TI_UINT32)&pMlme->assocInfo.assocRespBuffer[respBuffIEOffset];
            }
	   }
	   break;
    default:
        TRACE1(pMlme->hReport, REPORT_SEVERITY_ERROR, "Get param, Params is not supported, %d\n\n", pParam->content.mlmeLegacyAuthType);
        return PARAM_NOT_SUPPORTED;
    }

    return TI_OK;
}
TI_STATUS keyParserExternal_remove(struct _keyParser_t *pKeyParser, TI_UINT8 *pKeyData, TI_UINT32 keyDataLen)
{
	TI_STATUS				status;
	OS_802_11_KEY	 		*pKeyDesc;
    paramInfo_t  			macParam;
	encodedKeyMaterial_t    encodedKeyMaterial;
	TI_UINT8				broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
    TI_UINT8                keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH];

	if (pKeyData == NULL)
	{
TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: NULL KEY Data\n");
		return TI_NOK;
	}
	
	pKeyDesc = (OS_802_11_KEY*)pKeyData;

    if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK)
	{	/* Bit 31 should always be zero */
TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Remove TX bit in key index can't be 1\n");
		return TI_NOK;
	}
	if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK)
	{	/* Bits 8-29 should always be zero */
TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Remove none zero key index\n");
		return TI_NOK;
	}
	
	encodedKeyMaterial.keyId = pKeyDesc->KeyIndex;
	encodedKeyMaterial.keyLen = 0;
    encodedKeyMaterial.pData = (char *) keyBuffer;

	if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK)
	{	/* delete all pairwise keys or for the current BSSID */
		if (!MAC_EQUAL(pKeyDesc->BSSID, broadcastMacAddr))
		{
			MAC_COPY (keyBuffer, pKeyDesc->BSSID);
		} 
        else 
        {
			macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM;
			status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam);
			if (status != TI_OK)
			{
TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Cannot get MAC address !!!\n");
				return TI_NOK;
			}
			
			MAC_COPY (keyBuffer, macParam.content.ctrlDataCurrentBSSID);
		}

        status =  pKeyParser->pUcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial);
	}
	else
	{	/* delete all group keys or for the current BSSID */
		MAC_COPY (keyBuffer, broadcastMacAddr);
        status =  pKeyParser->pBcastKey->pKeyDerive->remove(pKeyParser->pUcastKey->pKeyDerive, &encodedKeyMaterial);
	}

	return status;
}
TI_STATUS keyParserExternal_recv(struct _keyParser_t *pKeyParser,
						  TI_UINT8 *pKeyData, TI_UINT32 keyDataLen)
{
	TI_STATUS						status;
	OS_802_11_KEY 	                *pKeyDesc;
	encodedKeyMaterial_t    		encodedKeyMaterial;
    paramInfo_t  					macParam;
	TI_BOOL                         macEqual2Associated=TI_FALSE;
	TI_BOOL							macIsBroadcast=TI_FALSE;
    TI_BOOL                         wepKey = TI_FALSE;
	TI_UINT8						broadcastMacAddr[MAC_ADDR_LEN] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
	TI_UINT8						nullMacAddr[MAC_ADDR_LEN] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
    TI_UINT8                        keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN+MAX_EXT_KEY_DATA_LENGTH];
    

    if (pKeyData == NULL)                             
	{                                                 
TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: NULL KEY Data\n");
		return TI_NOK;
	}
	
	pKeyDesc = (OS_802_11_KEY*)pKeyData;

    /* copy the key data, mac address and RSC */
	MAC_COPY (keyBuffer, pKeyDesc->BSSID);
	/* configure keyRSC value (if needed) */
    if (pKeyDesc->KeyIndex & EXT_KEY_RSC_KEY_MASK)
	{	/* set key recieve sequence counter */
        os_memoryCopy(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN], (TI_UINT8*)&(pKeyDesc->KeyRSC), KEY_RSC_LEN);
	}
    else
    {
        os_memoryZero(pKeyParser->hOs, &keyBuffer[MAC_ADDR_LEN], KEY_RSC_LEN);
    }

    /* check type and validity of keys */
    /* check MAC Address validity */
	macParam.paramType = CTRL_DATA_CURRENT_BSSID_PARAM;
	status = ctrlData_getParam(pKeyParser->hCtrlData, &macParam);

	if (status != TI_OK)
	{
TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Cannot get MAC address !!!\n");
        return TI_NOK;
	}

	/* check key length */
	if((pKeyDesc->KeyLength != WEP_KEY_LEN_40) && 
		(pKeyDesc->KeyLength != WEP_KEY_LEN_104) && 
		(pKeyDesc->KeyLength != WEP_KEY_LEN_232) &&
		(pKeyDesc->KeyLength != CKIP_KEY_LEN) && 
		(pKeyDesc->KeyLength != TKIP_KEY_LEN) && 
		(pKeyDesc->KeyLength != AES_KEY_LEN) )
		
	{
TRACE1(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Incorrect key length - %d \n", pKeyDesc->KeyLength);
		return TI_NOK;
	}
	if (MAC_EQUAL(macParam.content.ctrlDataCurrentBSSID, pKeyDesc->BSSID))
	{	
        macEqual2Associated = TI_TRUE;
   	}
	if (MAC_EQUAL (pKeyDesc->BSSID, broadcastMacAddr))
	{	
        macIsBroadcast = TI_TRUE;
   	}
	if ((pKeyDesc->KeyLength == WEP_KEY_LEN_40) || 
		(pKeyDesc->KeyLength == WEP_KEY_LEN_104) || 
		(pKeyDesc->KeyLength == WEP_KEY_LEN_232))
	{	/* In Add WEP the MAC address is nulled, since it's irrelevant */
        macEqual2Associated = TI_TRUE;
        wepKey = TI_TRUE;
   	}

    if (pKeyDesc->KeyIndex & EXT_KEY_SUPP_AUTHENTICATOR_MASK)
    {  /* The key is being set by an Authenticator - not allowed in IBSS mode */
    	if (pKeyParser->pParent->pParent->pParent->pAdmCtrl->networkMode == RSN_IBSS)
        {	/* in IBSS only Broadcast MAC is allowed */
        TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Authenticator set key in IBSS mode !!!\n");
        	return TI_NOK;
        }

    }

    if (pKeyDesc->KeyIndex & EXT_KEY_REMAIN_BITS_MASK)
    {  /* the reamining bits in the key index are not 0 (when they should be) */
TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Key index bits 8-27 should be 0 !!!\n");
		return TI_NOK;
    }
    
    encodedKeyMaterial.pData  = (char *) keyBuffer;
	/* Check key length according to the cipher suite - TKIP, etc...??? */
    if (wepKey)
    {
        if (!((pKeyDesc->KeyLength == WEP_KEY_LEN_40) || (pKeyDesc->KeyLength == WEP_KEY_LEN_104) 
              || (pKeyDesc->KeyLength == WEP_KEY_LEN_232)))
        {	/*Invalid key length*/
            TRACE1(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "WEP_KEY_PARSER: ERROR: Invalid Key length: %d !!!\n", pKeyDesc->KeyLength);
            return TI_NOK;
        }

        os_memoryCopy(pKeyParser->hOs, &keyBuffer[0], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength);
        if (MAC_EQUAL (nullMacAddr, pKeyDesc->BSSID))
        {   
            macIsBroadcast = TI_TRUE;
        } 

        encodedKeyMaterial.keyLen = pKeyDesc->KeyLength;
    }
    else /* this is TKIP or CKIP */
    {   
        if ((pKeyDesc->KeyLength == CKIP_KEY_LEN) && (pKeyParser->pPaeConfig->unicastSuite == TWD_CIPHER_CKIP))
        {
            os_memoryCopy(pKeyParser->hOs, &keyBuffer[0], pKeyDesc->KeyMaterial, pKeyDesc->KeyLength);
            encodedKeyMaterial.keyLen = pKeyDesc->KeyLength;
        }
        else
        {
            os_memoryCopy(pKeyParser->hOs, 
                          &keyBuffer[MAC_ADDR_LEN+KEY_RSC_LEN],
                          pKeyDesc->KeyMaterial, 
                          pKeyDesc->KeyLength);

            encodedKeyMaterial.keyLen = MAC_ADDR_LEN+KEY_RSC_LEN+pKeyDesc->KeyLength;
        }
    }

    encodedKeyMaterial.keyId  = pKeyDesc->KeyIndex;

TRACE2(pKeyParser->hReport, REPORT_SEVERITY_INFORMATION, "EXT_KEY_PARSER: Key received keyId=%x, keyLen=%d \n",						    pKeyDesc->KeyIndex, pKeyDesc->KeyLength                             );

    if (pKeyDesc->KeyIndex & EXT_KEY_PAIRWISE_GROUP_MASK)
    {	/* Pairwise key */
        /* check that the lower 8 bits of the key index are 0 */
        if (!wepKey && (pKeyDesc->KeyIndex & 0xff))
        {
TRACE0(pKeyParser->hReport, REPORT_SEVERITY_WARNING, "EXT_KEY_PARSER: ERROR: Pairwise key must have index 0 !!!\n");
            return TI_NOK;
        }

		if (macIsBroadcast)
		{
            TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: Broadcast MAC address for unicast !!!\n");
			return TI_NOK;
		}
		if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK)
		{	/* tx only pairwase key */
			/* set unicast keys */
        	if (pKeyParser->pUcastKey->recvSuccess!=NULL)
            {
        	status = pKeyParser->pUcastKey->recvSuccess(pKeyParser->pUcastKey, &encodedKeyMaterial);
            }
		} else {
			/* recieve only pairwase keys are not allowed */
            TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: recieve only pairwase keys are not allowed !!!\n");
            return TI_NOK;
		}

    }
    else
    {   /* set broadcast keys */
        if (!macIsBroadcast)
        {	/* not broadcast MAC */
        	if (pKeyParser->pParent->pParent->pParent->pAdmCtrl->networkMode == RSN_IBSS)
        	{	/* in IBSS only Broadcast MAC is allowed */
            TRACE0(pKeyParser->hReport, REPORT_SEVERITY_ERROR, "EXT_KEY_PARSER: ERROR: not broadcast MAC in IBSS mode !!!\n");
            	return TI_NOK;
        	}
        	else if (!macEqual2Associated)
        	{	/* ESS mode and MAC is different than the associated one */
        		/* save the key for later */
				status = TI_OK; /* pKeyParser->pBcastKey->saveKey(pKeyParser->pBcastKey, &encodedKey);*/
        	}
			else
			{	/* MAC is equal to the associated one - configure immediately */
                if (!wepKey)
				{
					MAC_COPY (keyBuffer, broadcastMacAddr);
				}
        		if (pKeyParser->pBcastKey->recvSuccess!=NULL)
                {
					status =  pKeyParser->pBcastKey->recvSuccess(pKeyParser->pBcastKey, &encodedKeyMaterial);
				}
			}
        }
		else
		{   /* MAC is broadcast - configure immediately */
			if (!wepKey)
			{
				MAC_COPY (keyBuffer, broadcastMacAddr);
			}
		 	
			/* set broadcast key */
			if (pKeyParser->pBcastKey->recvSuccess!=NULL)
			{
				status =  pKeyParser->pBcastKey->recvSuccess(pKeyParser->pBcastKey, &encodedKeyMaterial);
			}

			if (pKeyDesc->KeyIndex & EXT_KEY_TRANSMIT_MASK)
			{	/* Group key used to transmit */
				/* set as unicast key as well */
				if (pKeyParser->pUcastKey->recvSuccess!=NULL)
				{
					status = pKeyParser->pUcastKey->recvSuccess(pKeyParser->pUcastKey, &encodedKeyMaterial);
				}
			}
		}
    }
				  
	return status;
}