/*
 * Copyright (c) 1996, 2005 VIA Networking Technologies, Inc.
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 *
 * File: IEEE11h.c
 *
 * Purpose:
 *
 * Functions:
 *
 * Revision History:
 *
 * Author: Yiching Chen
 *
 * Date: Mar. 31, 2005
 *
 */

#include "ttype.h"
#include "tmacro.h"
#include "tether.h"
#include "IEEE11h.h"
#include "device.h"
#include "wmgr.h"
#include "rxtx.h"
#include "channel.h"

/*---------------------  Static Definitions -------------------------*/
static int          msglevel                =MSG_LEVEL_INFO;

#pragma pack(1)

typedef struct _WLAN_FRAME_ACTION {
    WLAN_80211HDR_A3    Header;
    unsigned char byCategory;
    unsigned char byAction;
    unsigned char abyVars[1];
} WLAN_FRAME_ACTION, *PWLAN_FRAME_ACTION;

typedef struct _WLAN_FRAME_MSRREQ {
    WLAN_80211HDR_A3    Header;
    unsigned char byCategory;
    unsigned char byAction;
    unsigned char byDialogToken;
    WLAN_IE_MEASURE_REQ sMSRReqEIDs[1];
} WLAN_FRAME_MSRREQ, *PWLAN_FRAME_MSRREQ;

typedef struct _WLAN_FRAME_MSRREP {
    WLAN_80211HDR_A3    Header;
    unsigned char byCategory;
    unsigned char byAction;
    unsigned char byDialogToken;
    WLAN_IE_MEASURE_REP sMSRRepEIDs[1];
} WLAN_FRAME_MSRREP, *PWLAN_FRAME_MSRREP;

typedef struct _WLAN_FRAME_TPCREQ {
    WLAN_80211HDR_A3    Header;
    unsigned char byCategory;
    unsigned char byAction;
    unsigned char byDialogToken;
    WLAN_IE_TPC_REQ     sTPCReqEIDs;
} WLAN_FRAME_TPCREQ, *PWLAN_FRAME_TPCREQ;

typedef struct _WLAN_FRAME_TPCREP {
    WLAN_80211HDR_A3    Header;
    unsigned char byCategory;
    unsigned char byAction;
    unsigned char byDialogToken;
    WLAN_IE_TPC_REP     sTPCRepEIDs;
} WLAN_FRAME_TPCREP, *PWLAN_FRAME_TPCREP;

#pragma pack()

// action field reference ieee 802.11h Table 20e
#define ACTION_MSRREQ       0
#define ACTION_MSRREP       1
#define ACTION_TPCREQ       2
#define ACTION_TPCREP       3
#define ACTION_CHSW         4

/*---------------------  Static Classes  ----------------------------*/

/*---------------------  Static Variables  --------------------------*/

/*---------------------  Static Functions  --------------------------*/
static bool s_bRxMSRReq(PSMgmtObject pMgmt, PWLAN_FRAME_MSRREQ pMSRReq,
		unsigned int uLength)
{
    size_t    uNumOfEIDs = 0;
    bool bResult = true;

    if (uLength <= WLAN_A3FR_MAXLEN) {
        memcpy(pMgmt->abyCurrentMSRReq, pMSRReq, uLength);
    }
    uNumOfEIDs = ((uLength - offsetof(WLAN_FRAME_MSRREQ, sMSRReqEIDs))/ (sizeof(WLAN_IE_MEASURE_REQ)));
    pMgmt->pCurrMeasureEIDRep = &(((PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep))->sMSRRepEIDs[0]);
    pMgmt->uLengthOfRepEIDs = 0;
    bResult = CARDbStartMeasure(pMgmt->pAdapter,
                                ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->sMSRReqEIDs,
                                uNumOfEIDs
                                );
    return (bResult);
}


static bool s_bRxTPCReq(PSMgmtObject pMgmt, PWLAN_FRAME_TPCREQ pTPCReq, unsigned char byRate, unsigned char byRSSI)
{
    PWLAN_FRAME_TPCREP  pFrame;
    PSTxMgmtPacket      pTxPacket = NULL;


    pTxPacket = (PSTxMgmtPacket)pMgmt->pbyMgmtPacketPool;
    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));

    pFrame = (PWLAN_FRAME_TPCREP)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));

    pFrame->Header.wFrameCtl = (   WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
                                    WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
                                );

    memcpy( pFrame->Header.abyAddr1, pTPCReq->Header.abyAddr2, WLAN_ADDR_LEN);
    memcpy( pFrame->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
    memcpy( pFrame->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);

    pFrame->byCategory = 0;
    pFrame->byAction = 3;
    pFrame->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;

    pFrame->sTPCRepEIDs.byElementID = WLAN_EID_TPC_REP;
    pFrame->sTPCRepEIDs.len = 2;
    pFrame->sTPCRepEIDs.byTxPower = CARDbyGetTransmitPower(pMgmt->pAdapter);
    switch (byRate) {
        case RATE_54M:
            pFrame->sTPCRepEIDs.byLinkMargin = 65 - byRSSI;
            break;
        case RATE_48M:
            pFrame->sTPCRepEIDs.byLinkMargin = 66 - byRSSI;
            break;
        case RATE_36M:
            pFrame->sTPCRepEIDs.byLinkMargin = 70 - byRSSI;
            break;
        case RATE_24M:
            pFrame->sTPCRepEIDs.byLinkMargin = 74 - byRSSI;
            break;
        case RATE_18M:
            pFrame->sTPCRepEIDs.byLinkMargin = 77 - byRSSI;
            break;
        case RATE_12M:
            pFrame->sTPCRepEIDs.byLinkMargin = 79 - byRSSI;
            break;
        case RATE_9M:
            pFrame->sTPCRepEIDs.byLinkMargin = 81 - byRSSI;
            break;
        case RATE_6M:
        default:
            pFrame->sTPCRepEIDs.byLinkMargin = 82 - byRSSI;
            break;
    }

    pTxPacket->cbMPDULen = sizeof(WLAN_FRAME_TPCREP);
    pTxPacket->cbPayloadLen = sizeof(WLAN_FRAME_TPCREP) - WLAN_HDR_ADDR3_LEN;
    if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
        return (false);
    return (true);
//    return (CARDbSendPacket(pMgmt->pAdapter, pFrame, PKT_TYPE_802_11_MNG, sizeof(WLAN_FRAME_TPCREP)));

}


/*---------------------  Export Variables  --------------------------*/

/*---------------------  Export Functions  --------------------------*/


/*+
 *
 * Description:
 *      Handles action management frames.
 *
 * Parameters:
 *  In:
 *      pMgmt           - Management Object structure
 *      pRxPacket       - Received packet
 *  Out:
 *      none
 *
 * Return Value: None.
 *
-*/
bool
IEEE11hbMgrRxAction (
    void *pMgmtHandle,
    void *pRxPacket
    )
{
    PSMgmtObject            pMgmt = (PSMgmtObject) pMgmtHandle;
    PWLAN_FRAME_ACTION      pAction = NULL;
    unsigned int uLength = 0;
    PWLAN_IE_CH_SW          pChannelSwitch = NULL;


    // decode the frame
    uLength = ((PSRxMgmtPacket)pRxPacket)->cbMPDULen;
    if (uLength > WLAN_A3FR_MAXLEN) {
        return (false);
    }


    pAction = (PWLAN_FRAME_ACTION) (((PSRxMgmtPacket)pRxPacket)->p80211Header);

    if (pAction->byCategory == 0) {
        switch (pAction->byAction) {
            case ACTION_MSRREQ:
                return (s_bRxMSRReq(pMgmt, (PWLAN_FRAME_MSRREQ) pAction, uLength));
                break;
            case ACTION_MSRREP:
                break;
            case ACTION_TPCREQ:
                return (s_bRxTPCReq(pMgmt,
                                    (PWLAN_FRAME_TPCREQ) pAction,
                                    ((PSRxMgmtPacket)pRxPacket)->byRxRate,
                                    (unsigned char) ((PSRxMgmtPacket)pRxPacket)->uRSSI));
                break;
            case ACTION_TPCREP:
                break;
            case ACTION_CHSW:
                pChannelSwitch = (PWLAN_IE_CH_SW) (pAction->abyVars);
                if ((pChannelSwitch->byElementID == WLAN_EID_CH_SWITCH) &&
                    (pChannelSwitch->len == 3)) {
                    // valid element id
                    CARDbChannelSwitch( pMgmt->pAdapter,
                                        pChannelSwitch->byMode,
                                        get_channel_mapping(pMgmt->pAdapter, pChannelSwitch->byChannel, pMgmt->eCurrentPHYMode),
                                        pChannelSwitch->byCount
                                        );
                }
                break;
            default:
                DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Action = %d\n", pAction->byAction);
                break;
        }
    } else {
        DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO"Unknown Category = %d\n", pAction->byCategory);
        pAction->byCategory |= 0x80;

       //return (CARDbSendPacket(pMgmt->pAdapter, pAction, PKT_TYPE_802_11_MNG, uLength));
        return (true);
    }
    return (true);
}


bool IEEE11hbMSRRepTx (
    void *pMgmtHandle
    )
{
    PSMgmtObject            pMgmt = (PSMgmtObject) pMgmtHandle;
    PWLAN_FRAME_MSRREP      pMSRRep = (PWLAN_FRAME_MSRREP) (pMgmt->abyCurrentMSRRep + sizeof(STxMgmtPacket));
    size_t                    uLength = 0;
    PSTxMgmtPacket          pTxPacket = NULL;

    pTxPacket = (PSTxMgmtPacket)pMgmt->abyCurrentMSRRep;
    memset(pTxPacket, 0, sizeof(STxMgmtPacket) + WLAN_A3FR_MAXLEN);
    pTxPacket->p80211Header = (PUWLAN_80211HDR)((unsigned char *)pTxPacket + sizeof(STxMgmtPacket));


    pMSRRep->Header.wFrameCtl = (   WLAN_SET_FC_FTYPE(WLAN_FTYPE_MGMT) |
                                    WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_ACTION)
                                );

    memcpy( pMSRRep->Header.abyAddr1, ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->Header.abyAddr2, WLAN_ADDR_LEN);
    memcpy( pMSRRep->Header.abyAddr2, CARDpGetCurrentAddress(pMgmt->pAdapter), WLAN_ADDR_LEN);
    memcpy( pMSRRep->Header.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN);

    pMSRRep->byCategory = 0;
    pMSRRep->byAction = 1;
    pMSRRep->byDialogToken = ((PWLAN_FRAME_MSRREQ) (pMgmt->abyCurrentMSRReq))->byDialogToken;

    uLength = pMgmt->uLengthOfRepEIDs + offsetof(WLAN_FRAME_MSRREP, sMSRRepEIDs);

    pTxPacket->cbMPDULen = uLength;
    pTxPacket->cbPayloadLen = uLength - WLAN_HDR_ADDR3_LEN;
    if (csMgmt_xmit(pMgmt->pAdapter, pTxPacket) != CMD_STATUS_PENDING)
        return (false);
    return (true);
//    return (CARDbSendPacket(pMgmt->pAdapter, pMSRRep, PKT_TYPE_802_11_MNG, uLength));

}

