/** @file router_transport.c
 *
 *
 * Copyright (C) Cambridge Silicon Radio Ltd 2006-2010. All rights reserved.
 *
 * Refer to LICENSE.txt included with this source code for details on
 * the license terms.
 *
 ****************************************************************************/

#include "unifi_priv.h"

#include "csr_sched.h"
#include "csr_msgconv.h"

#include "sme_userspace.h"

#include "csr_wifi_hostio_prim.h"
#include "csr_wifi_router_lib.h"
#include "csr_wifi_router_sef.h"
#include "csr_wifi_router_converter_init.h"
#include "csr_wifi_router_ctrl_lib.h"
#include "csr_wifi_router_ctrl_sef.h"
#include "csr_wifi_router_ctrl_converter_init.h"
#include "csr_wifi_sme_prim.h"
#include "csr_wifi_sme_sef.h"
#include "csr_wifi_sme_converter_init.h"
#ifdef CSR_SUPPORT_WEXT
#ifdef CSR_SUPPORT_WEXT_AP
#include "csr_wifi_nme_ap_prim.h"
#include "csr_wifi_nme_ap_sef.h"
#include "csr_wifi_nme_ap_converter_init.h"
#endif
#endif

static unifi_priv_t *drvpriv = NULL;
void CsrWifiRouterTransportInit(unifi_priv_t *priv)
{
    unifi_trace(priv, UDBG1, "CsrWifiRouterTransportInit: \n");

    drvpriv = priv;
    (void)CsrMsgConvInit();
    CsrWifiRouterConverterInit();
    CsrWifiRouterCtrlConverterInit();
    CsrWifiSmeConverterInit();
#ifdef CSR_SUPPORT_WEXT
#ifdef CSR_SUPPORT_WEXT_AP
    CsrWifiNmeApConverterInit();
#endif
#endif
}

void CsrWifiRouterTransportRecv(unifi_priv_t *priv, u8* buffer, size_t bufferLength)
{
    CsrMsgConvMsgEntry* msgEntry;
    u16 primType;
    CsrSchedQid src;
    CsrSchedQid dest;
    u16 msgType;
    size_t offset = 0;
    CsrWifiFsmEvent* msg;

    /* Decode the prim and message type */
    CsrUint16Des(&primType, buffer, &offset);
    CsrUint16Des(&src, buffer, &offset);
    CsrUint16Des(&dest, buffer, &offset);
    CsrUint16Des(&msgType, buffer, &offset);
    offset -= 2; /* Adjust as the Deserialise Function will read this as well */

    unifi_trace(priv, UDBG4, "CsrWifiRouterTransportRecv: primType=0x%.4X, msgType=0x%.4X, bufferLength=%d\n",
                primType, msgType, bufferLength);

    /* Special handling for HOSTIO messages.... */
    if (primType == CSR_WIFI_HOSTIO_PRIM)
    {
        CsrWifiRouterCtrlHipReq req = {{CSR_WIFI_ROUTER_CTRL_HIP_REQ, CSR_WIFI_ROUTER_CTRL_PRIM, dest, src, NULL}, 0, NULL, 0, NULL, 0, NULL};

        req.mlmeCommandLength = bufferLength;
        req.mlmeCommand = buffer;

        offset += 8;/* Skip the id, src, dest and slot number */
        CsrUint16Des(&req.dataRef1Length, buffer, &offset);
        offset += 2; /* Skip the slot number */
        CsrUint16Des(&req.dataRef2Length, buffer, &offset);

        if (req.dataRef1Length)
        {
            u16 dr1Offset = (bufferLength - req.dataRef2Length) - req.dataRef1Length;
            req.dataRef1 = &buffer[dr1Offset];
        }

        if (req.dataRef2Length)
        {
            u16 dr2Offset = bufferLength - req.dataRef2Length;
            req.dataRef2 = &buffer[dr2Offset];
        }

        /* Copy the hip data but strip off the prim type */
        req.mlmeCommandLength -= (req.dataRef1Length + req.dataRef2Length + 6);
        req.mlmeCommand = &buffer[6];

        CsrWifiRouterCtrlHipReqHandler(priv, &req.common);
        return;
    }

    msgEntry = CsrMsgConvFindEntry(primType, msgType);
    if (!msgEntry)
    {
        unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n",
                    primType, msgType);
        dump(buffer, bufferLength);
        return;
    }

    msg = (CsrWifiFsmEvent*)(msgEntry->deserFunc)(&buffer[offset], bufferLength - offset);

    msg->primtype = primType;
    msg->type = msgType;
    msg->source = src;
    msg->destination = dest;

    switch(primType)
    {
    case CSR_WIFI_ROUTER_CTRL_PRIM:
        CsrWifiRouterCtrlDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_CTRL_PRIM_DOWNSTREAM_LOWEST](priv, msg);
        CsrWifiRouterCtrlFreeDownstreamMessageContents(CSR_WIFI_ROUTER_CTRL_PRIM, msg);
        break;
    case CSR_WIFI_ROUTER_PRIM:
        CsrWifiRouterDownstreamStateHandlers[msg->type - CSR_WIFI_ROUTER_PRIM_DOWNSTREAM_LOWEST](priv, msg);
        CsrWifiRouterFreeDownstreamMessageContents(CSR_WIFI_ROUTER_PRIM, msg);
        break;
        case CSR_WIFI_SME_PRIM:
            CsrWifiSmeUpstreamStateHandlers[msg->type - CSR_WIFI_SME_PRIM_UPSTREAM_LOWEST](priv, msg);
            CsrWifiSmeFreeUpstreamMessageContents(CSR_WIFI_SME_PRIM, msg);
            break;
#ifdef CSR_SUPPORT_WEXT
#ifdef CSR_SUPPORT_WEXT_AP
        case CSR_WIFI_NME_AP_PRIM:
            CsrWifiNmeApUpstreamStateHandlers(priv, msg);
            CsrWifiNmeApFreeUpstreamMessageContents(CSR_WIFI_NME_AP_PRIM, msg);
            break;
#endif
#endif
        default:
            unifi_error(priv, "CsrWifiRouterTransportDeserialiseAndSend unhandled prim type 0x%.4X\n", primType);
            break;
    }
    kfree(msg);
}

static void CsrWifiRouterTransportSerialiseAndSend(u16 primType, void* msg)
{
    CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)msg;
    CsrMsgConvMsgEntry* msgEntry;
    size_t msgSize;
    size_t encodeBufferLen = 0;
    size_t offset = 0;
    u8* encodeBuffer;

    unifi_trace(drvpriv, UDBG4, "CsrWifiRouterTransportSerialiseAndSend: primType=0x%.4X, msgType=0x%.4X\n",
                primType, evt->type);

    msgEntry = CsrMsgConvFindEntry(primType, evt->type);
    if (!msgEntry)
    {
        unifi_error(drvpriv, "CsrWifiRouterTransportSerialiseAndSend can not process the message. primType=0x%.4X, msgType=0x%.4X\n",
                    primType, evt->type);
        return;
    }

    msgSize = 6 + (msgEntry->sizeofFunc)((void*)msg);

    encodeBuffer = kmalloc(msgSize, GFP_KERNEL);

    /* Encode PrimType */
    CsrUint16Ser(encodeBuffer, &encodeBufferLen, primType);
    CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->source);
    CsrUint16Ser(encodeBuffer, &encodeBufferLen, evt->destination);

    (void)(msgEntry->serFunc)(&encodeBuffer[encodeBufferLen], &offset, msg);
    encodeBufferLen += offset;

    uf_sme_queue_message(drvpriv, encodeBuffer, encodeBufferLen);

    /* Do not use msgEntry->freeFunc because the memory is owned by the driver */
    kfree(msg);
}

#if defined(CSR_LOG_ENABLE) && defined(CSR_LOG_INCLUDE_FILE_NAME_AND_LINE_NUMBER)
void CsrSchedMessagePutStringLog(CsrSchedQid q, u16 mi, void *mv, u32 line, char *file)
#else
void CsrSchedMessagePut(CsrSchedQid q, u16 mi, void *mv)
#endif
{
    CsrWifiFsmEvent* evt = (CsrWifiFsmEvent*)mv;
    evt->destination = q;
    CsrWifiRouterTransportSerialiseAndSend(mi, mv);
}

