/**
*
* assoc_recv - Recive a message from the AP
*
* \b Description: 
*
* Parse a message form the AP and perform the appropriate event.
*
* \b ARGS:
*
*  I   - hAssoc - Association SM context  \n
*  I   - pFrame - Frame recieved  \n
*
* \b RETURNS:
*
*  TI_OK if successful, TI_NOK otherwise.
*
* \sa assoc_Start, assoc_Stop
*/
TI_STATUS assoc_recv(TI_HANDLE hAssoc, mlmeFrameInfo_t *pFrame)
{
    TI_STATUS       status;
    assoc_t         *pHandle = (assoc_t*)hAssoc;
    TTwdParamInfo   tTwdParam;
    TI_UINT16           rspStatus;

    if (pHandle == NULL)
    {
        return TI_NOK;
    }

    /* ensure that the SM is waiting for assoc response */
    if(pHandle->currentState != ASSOC_SM_STATE_WAIT)
        return TI_OK;

    
    if ((pFrame->subType != ASSOC_RESPONSE) && (pFrame->subType != RE_ASSOC_RESPONSE))
    {
        return TI_NOK;
    }

    /* check response status */
    rspStatus  = pFrame->content.assocRsp.status;
    
    if (rspStatus == 0)
    {
        TRsnData        rsnData;
        dot11_RSN_t *pRsnIe;
        TI_UINT8       curRsnData[255];
        TI_UINT8       rsnAssocIeLen;
        TI_UINT8        length = 0;


        TRACE0(pHandle->hReport, REPORT_SEVERITY_SM, "ASSOC_SM: DEBUG Success associating to AP \n");
        
        /* set AID to HAL */
        tTwdParam.paramType = TWD_AID_PARAM_ID;
        tTwdParam.content.halCtrlAid  = pFrame->content.assocRsp.aid;
        TWD_SetParam (pHandle->hTWD, &tTwdParam);
        

        /* Get the RSN IE data */
        pRsnIe = pFrame->content.assocRsp.pRsnIe;
        while (length < pFrame->content.assocRsp.rsnIeLen && (pFrame->content.assocRsp.rsnIeLen < 255))
        {
            curRsnData[0+length] = pRsnIe->hdr[0];
            curRsnData[1+length] = pRsnIe->hdr[1];
            os_memoryCopy(pHandle->hOs, &curRsnData[2+length], (void *)pRsnIe->rsnIeData, pRsnIe->hdr[1]); 
            length += pRsnIe->hdr[1] + 2;
            pRsnIe += 1;
        }
        
        if (pFrame->content.assocRsp.rsnIeLen != 0)
        {
            rsnData.pIe = curRsnData;
            rsnData.ieLen = pFrame->content.assocRsp.rsnIeLen;
            rsnData.privacy =  ((pFrame->content.assocRsp.capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) ? TI_TRUE : TI_FALSE;
            rsn_setSite(pHandle->hRsn, &rsnData, NULL, &rsnAssocIeLen);
        }
/**
*
* assoc_recv - Recive a message from the AP
*
* \b Description: 
*
* Parse a message form the AP and perform the appropriate event.
*
* \b ARGS:
*
*  I   - hAssoc - Association SM context  \n
*  I   - pFrame - Frame recieved  \n
*
* \b RETURNS:
*
*  OK if successful, NOK otherwise.
*
* \sa assoc_Start, assoc_Stop
*/
TI_STATUS assoc_recv(TI_HANDLE hAssoc, mlmeFrameInfo_t *pFrame)
{
	TI_STATUS 		status;
	assoc_t			*pHandle;
	whalParamInfo_t		whalParam;
	UINT16			rspStatus;

	pHandle = (assoc_t*)hAssoc;

	/* ensure that the SM is waiting for assoc response */
	if(pHandle->currentState != ASSOC_SM_STATE_WAIT)
		return OK;

	if (pHandle == NULL)
	{
		return NOK;
	}
	
	if ((pFrame->subType != ASSOC_RESPONSE) && (pFrame->subType != RE_ASSOC_RESPONSE))
	{
		return NOK;
	}

    /* check response status */
	rspStatus  = pFrame->content.assocRsp.status;
	
	if (rspStatus == 0)
	{
		rsnData_t	rsnData;
        dot11_RSN_t *pRsnIe;
        UINT8       curRsnData[255];
        UINT8       rsnAssocIeLen;
        UINT16      length=0;


        WLAN_REPORT_SM(pHandle->hReport, ASSOC_MODULE_LOG,
				  ("ASSOC_SM: DEBUG Success associating to AP \n"));
		
		/* set AID to HAL */
		whalParam.paramType = HAL_CTRL_AID_PARAM;
		whalParam.content.halCtrlAid  = pFrame->content.assocRsp.aid;
		whalCtrl_SetParam(pHandle->hHalCtrl, &whalParam);
        

        /* Get the RSN IE data */
        pRsnIe = pFrame->content.assocRsp.pRsnIe;
        while ((length < pFrame->content.assocRsp.rsnIeLen) && (pFrame->content.assocRsp.rsnIeLen < 255))
        {
            if ((pRsnIe->hdr.eleLen + length + 2) > 255) { /* Dm: Security fix */
                WLAN_REPORT_ERROR(pHandle->hReport, ASSOC_MODULE_LOG, 
                                  ("%s - Security Error: %u > 255\n", __FUNCTION__,(pRsnIe->hdr.eleLen + length + 2)));
                break;
            }
            curRsnData[0+length] = pRsnIe->hdr.eleId;
            curRsnData[1+length] = pRsnIe->hdr.eleLen;
            os_memoryCopy(pHandle->hOs, &curRsnData[2+length], (void *)pRsnIe->rsnIeData, pRsnIe->hdr.eleLen); 
            length += pRsnIe->hdr.eleLen+2;
            pRsnIe += 1;
        }
        
		if (pFrame->content.assocRsp.rsnIeLen != 0)
		{
			rsnData.pIe = curRsnData;
			rsnData.ieLen = pFrame->content.assocRsp.rsnIeLen;
			rsnData.privacy =  ((pFrame->content.assocRsp.capabilities >> CAP_PRIVACY_SHIFT) & CAP_PRIVACY_MASK) ? TRUE : FALSE;
			rsn_setSite(pHandle->hRsn, &rsnData, NULL, &rsnAssocIeLen);
		}