//------------------------------------------------------------------------------
//! @file WiMOD_SAP_DEVMGMT_Lorawan.cpp
//! @ingroup WiMOD_SAP_DEVMGMT_LORAWAN
//! <!------------------------------------------------------------------------->
//! @brief Implementation of the commands of the DeviceManagement SericeAccessPoint for LoRaWAN FW
//! @version 0.1
//! <!------------------------------------------------------------------------->
//!
//!
//!
//! <!--------------------------------------------------------------------------
//! Copyright (c) 2021
//! IMST GmbH
//! Carl-Friedrich Gauss Str. 2-4
//! 47475 Kamp-Lintfort
//! --------------------------------------------------------------------------->
//! @author (FB), IMST
//! <!--------------------------------------------------------------------------
//! Target OS:    none
//! Target CPU:   tbd
//! Compiler:     tbd
//! --------------------------------------------------------------------------->
//! @internal
//! @par Revision History:
//! <PRE>
//!-----------------------------------------------------------------------------
//! Version | Date       | Author | Comment
//!-----------------------------------------------------------------------------
//!
//! </PRE>
//------------------------------------------------------------------------------

/*
 * THIS IS AN EXAMPLE IMPLEMENTATION ACCORDING THE THE HCI SPEC: V2.1
 * FOR FIRMWARE: LoRaWAN EndNode Firmware
 */

//------------------------------------------------------------------------------
//
// Section Includes Files
//
//------------------------------------------------------------------------------


#include "WiMOD_SAP_DEVMGMT_Lorawan.h"

//------------------------------------------------------------------------------
//
// Section public functions
//
//------------------------------------------------------------------------------

//-----------------------------------------------------------------------------
/**
 * @brief Constructor
 *
 * @param hci       Pointer to HCI processor object
 *
 * @param buffer    pointer to storage area for building tx frames; MUST BE VALID
 *
 * @param bufferSize    size of the buffer
 *
 */
WiMOD_SAP_DevMgmt_Lorawan::WiMOD_SAP_DevMgmt_Lorawan(TWiMODLRHCI* hci, UINT8* buffer, UINT16 bufferSize) :
    WiMOD_SAP_DevMgmt(hci, buffer, bufferSize)
{

}

//-----------------------------------------------------------------------------
/**
 * @brief Destructor
 */
WiMOD_SAP_DevMgmt_Lorawan::~WiMOD_SAP_DevMgmt_Lorawan(void)
{

}


//------------------------------------------------------------------------------

TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::GetDeviceInfo(TWiMODLR_DevMgmt_DevInfo* info, UINT8* statusRsp) {
    (void) info;
    // not supported in this firmware
    return unsupportedCmd(statusRsp);
}


TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::GetDeviceInfo(TWiMODLR_DevMgmt_DevInfoLoRaWan* info, UINT8* statusRsp)
{
    TWiMODLRResultCodes result = WiMODLR_RESULT_TRANMIT_ERROR;
    UINT8              offset = WiMODLR_HCI_RSP_CMD_PAYLOAD_POS;

    if (info && statusRsp) {
        result = HciParser->SendHCIMessage(DEVMGMT_SAP_ID,
                                           DEVMGMT_MSG_GET_DEVICEINFO_REQ,
                                           DEVMGMT_MSG_GET_DEVICEINFO_RSP,
                                           NULL, 0);

        if (result == WiMODLR_RESULT_OK) {
            const TWiMODLR_HCIMessage& rx = HciParser->GetRxMessage();

            // extract data from response
            info->Status     = rx.Payload[WiMODLR_HCI_RSP_STATUS_POS];
            info->ModuleType = rx.Payload[offset++];
            info->DevAdr     = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->DevID      = NTOH32(&rx.Payload[offset]);
            offset += 0x04;

            *statusRsp = rx.Payload[WiMODLR_HCI_RSP_STATUS_POS];
        }
    }
    return result;
}

//-----------------------------------------------------------------------------


TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::GetSystemStatus(TWiMODLR_DevMgmt_SystemStatus* info, UINT8* statusRsp) {
    (void) info;
    // not supported in this firmware
    return unsupportedCmd(statusRsp);
}

//-----------------------------------------------------------------------------
/**
 * @brief GetSystemStatus Cmd - Get basic info about the system status of WiMOD
 *
 *
 * @param   info        pointer to store the received information
 * @param   statusRsp   pointer to store status byte of response mesg from WiMOD
 *
 * @retval WiMODLR_RESULT_OK     if command transmit to WiMOD was ok
 */
TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::GetSystemStatus(TWiMODLR_DevMgmt_SystemStatusLorawan* info, UINT8* statusRsp)
{
    TWiMODLRResultCodes result = WiMODLR_RESULT_TRANMIT_ERROR;
    UINT8              offset = WiMODLR_HCI_RSP_STATUS_POS;

    if (info && statusRsp) {
        result = HciParser->SendHCIMessage(DEVMGMT_SAP_ID,
                                           DEVMGMT_MSG_GET_SYSTEM_STATUS_REQ,
                                           DEVMGMT_MSG_GET_SYSTEM_STATUS_RSP,
                                           NULL, 0);

        if (result == WiMODLR_RESULT_OK) {
            const TWiMODLR_HCIMessage& rx = HciParser->GetRxMessage();

            info->Status              = rx.Payload[offset++];
            info->SysTickResolution   = rx.Payload[offset++];
            info->SysTickCounter      = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->RtcTime             = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->NvmStatus           = NTOH16(&rx.Payload[offset]);
            offset += 0x02;
            info->BatteryStatus       = NTOH16(&rx.Payload[offset]);
            offset += 0x02;
            info->ExtraStatus         = NTOH16(&rx.Payload[offset]);
            offset += 0x02;
            info->TxUDataPackets      = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->TxCDataPackets      = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->TxError             = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->Rx1UDataPackets     = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->Rx1CDataPackets     = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->Rx1MicError         = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->Rx2UDataPackets     = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->Rx2CDataPackets     = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->Rx2MicError         = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->TxJoin              = NTOH32(&rx.Payload[offset]);
            offset += 0x04;
            info->RxAccept            = NTOH32(&rx.Payload[offset]);
            offset += 0x04;

            *statusRsp = rx.Payload[WiMODLR_HCI_RSP_STATUS_POS];
        }
    }
    return result;
}

//-----------------------------------------------------------------------------


TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::GetRadioConfig(TWiMODLR_DevMgmt_RadioConfig* radioCfg, UINT8* statusRsp) {
    (void) radioCfg;
    // not supported in this firmware
    return unsupportedCmd(statusRsp);
}

TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::SetRadioConfig(const TWiMODLR_DevMgmt_RadioConfig* radioCfg, UINT8* statusRsp) {
    (void) radioCfg;
    // not supported in this firmware
    return unsupportedCmd(statusRsp);
}

TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::ResetRadioConfig(UINT8* statusRsp){
    // not supported in this firmware
    return unsupportedCmd(statusRsp);
}

TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::SetRadioMode(const TRadioCfg_RadioMode radioMode, UINT8* statusRsp){
    (void) radioMode;
    // not supported in this firmware
    return unsupportedCmd(statusRsp);
}

TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::SetAesKey(const UINT8* key, UINT8* statusRsp) {
    (void) key;
    // not supported in this firmware
    return unsupportedCmd(statusRsp);
}

TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::GetAesKey(UINT8* key, UINT8* statusRsp) {
    (void) key;
    // not supported in this firmware
    return unsupportedCmd(statusRsp);
}





//------------------------------------------------------------------------------
//
// Section protected functions
//
//------------------------------------------------------------------------------
/**
 * @internal
 * @brief default cmd handler for unknown / unsupported commands
 * @params statusRsp    pointer to HCI status response code to set
 * @endinternal
 */
TWiMODLRResultCodes WiMOD_SAP_DevMgmt_Lorawan::unsupportedCmd(UINT8* statusRsp) {
    if (statusRsp) {
        *statusRsp = DEVMGMT_STATUS_CMD_NOT_SUPPORTED;
    }
    return WiMODLR_RESULT_TRANMIT_ERROR;
}


//------------------------------------------------------------------------------
//
// Section private functions
//
//------------------------------------------------------------------------------




