//------------------------------------------------------------------------------
//! @file WiMODProLink.cpp
//! @ingroup WiMODPROLINK
//! <!------------------------------------------------------------------------->
//! @brief High-level Interface class to the WiMOD module running the WiMOD LoRaWAN ProLink firmware
//! @version 0.1
//! <!------------------------------------------------------------------------->
//!
//!
//!
//! <!--------------------------------------------------------------------------
//! Copyright (c) 2022
//! 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>
//------------------------------------------------------------------------------

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

#include "WiMODProLink.h"
#include <string.h>
#include "../utils/StrToIntConverter.h"

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

//-----------------------------------------------------------------------------
/**
 * @brief Constructor
 *
 * This function requires a cpp reference to the serial interface object
 * that is to be used for communication.
 *
 * @code
 * #include <WiMODProLink.h>
 *
 * WiMODProLink wimod(Serial3);  // use the Arduino Serial3 as serial interface
 *
 * void setup() {
 *  // init stack
 *  wimod.begin();
 *  ...
 * }
 * @endcode
 *
 */
WiMODProLink::WiMODProLink(Stream& s) :
    TWiMODLRHCI(s),
    SapDevMgmt(this, txBuffer, WiMOD_PROLINK_TX_BUFFER_SIZE),
    SapLoRaWan(this, txBuffer, WiMOD_PROLINK_TX_BUFFER_SIZE),
    SapRadioLink(this, txBuffer, WiMOD_PROLINK_TX_BUFFER_SIZE),
    SapGeneric(this, txBuffer, WiMOD_PROLINK_TX_BUFFER_SIZE)
{

    localStatusRsp = 0;
    cmdResult      = false;
    localHciRes    = WiMODLR_RESULT_TRANMIT_ERROR;
    lastHciRes     = WiMODLR_RESULT_TRANMIT_ERROR;
    lastStatusRsp  = 0;
    memset(txBuffer, 0x00, WiMOD_PROLINK_TX_BUFFER_SIZE);
}

//-----------------------------------------------------------------------------
/**
 * @brief Desctructor
 */
WiMODProLink::~WiMODProLink(void) {

}

//-----------------------------------------------------------------------------
/**
 * @brief This function must be called once before any other service can be used
 *
 * @code
 * #include <WiMODProLink.h>
 *
 * WiMODProLink wimod(Serial3);  // use the Arduino Serial3 as serial interface
 *
 * void setup() {
 *  // init stack
 *  wimod.begin();
 *  ...
 * }
 * @endcode
 */
void WiMODProLink::begin(TProLinkLoRaWANregion region) {
    TWiMODLRHCI::begin();
//    isOpen = true;
    SapLoRaWan.setRegion(region);
}

//! @cond Doxygen_Suppress
void WiMODProLink::beginAndAutoSetup(void) {
    TWiMODLRHCI::begin();
//    isOpen = true;
    SapLoRaWan.setRegion(ProLink_LoRaWAN_Region_EU868); // default pre set
    this->autoSetupSupportedRegion();
}
//! @endcond

//-----------------------------------------------------------------------------
/**
 * @brief Shut shut down function
 */
void WiMODProLink::end(void) {
    TWiMODLRHCI::end();
//    HciDispatcher.end();
}

//! @cond Doxygen_Suppress
void WiMODProLink::autoSetupSupportedRegion(void) {
  TWiMODLORAWAN_SupportedBands cfg;
  TProLinkLoRaWANregion        region = ProLink_LoRaWAN_Region_EU868;
  UINT8                          i;

  // ask the module which firmware region is supported
  localHciRes = SapLoRaWan.GetSupportedBands(&cfg, &localStatusRsp);

  // check cmd result
  if ((WiMODLR_RESULT_OK == localHciRes)
      && (localStatusRsp == DEVMGMT_STATUS_OK)) {
    cmdResult = true;

  }
  // setup region a cmd was successful
  if (cmdResult) {
    for (i = 0; i < cfg.NumOfEntries; i++) {
      if ((cfg.BandIndex[i] == (uint8_t) ProLink_LoRaWAN_FreqBand_EU_868) ||
              (cfg.BandIndex[i] == ProLink_LoRaWAN_FreqBand_EU_868_RX2_SF9))
      {
        region = ProLink_LoRaWAN_Region_EU868;
        break;
      }

      if (cfg.BandIndex[i] == ProLink_LoRaWAN_FreqBand_US_915)
      {
        region = ProLink_LoRaWAN_Region_US915;
        break;
      }

      if (cfg.BandIndex[i] ==  ProLink_LoRaWAN_FreqBand_AU_915)
      {
        region = ProLink_LoRaWAN_Region_AU915;
        break;
      }

      if ((cfg.BandIndex[i] == ProLink_LoRaWAN_FreqBand_AS_923_1)     ||
              (cfg.BandIndex[i] == ProLink_LoRaWAN_FreqBand_AS_923_2) ||
              (cfg.BandIndex[i] == ProLink_LoRaWAN_FreqBand_AS_923_3) )
      {
        region = ProLink_LoRaWAN_Region_AS923;
        break;
      }
      if ((cfg.BandIndex[i] == ProLink_LoRaWAN_FreqBand_IN_865) ||
          (cfg.BandIndex[i] == ProLink_LoRaWAN_FreqBand_IN_865_RX2_SF8))
      {
        region = ProLink_LoRaWAN_Region_IN865;
        break;
      }


      if (cfg.BandIndex[i] == ProLink_LoRaWAN_FreqBand_RU_868)
      {
        region = ProLink_LoRaWAN_Region_RU868;
        break;
      }
      if (cfg.BandIndex[i] == GLOBALLINK24_BAND_WW_2G4 )
      {
          region = ProLink_LoRaWAN_Region_proprietary_WW2G4;
          break;
      }
    }
    SapLoRaWan.setRegion(region);
  }
  return;
}
//! @endcond

//! @cond Doxygen_Suppress

/**
 * @brief print out some basic infos about the radio module on a given stream
 *
 * @param   s   reference to the output stream to use
 */
void WiMODProLink::PrintBasicDeviceInfo(Stream& s) {

    TWiMODLR_DevMgmt_DevInfoLoRaWan devInfo;
    TWiMODLR_DevMgmt_FwInfo         fwInfo;
    uint8_t                         devEUI[8];

    s.print(F("\r\n"));
    s.print(F("General Info Radio-Module:\r\n"));
    s.print(F("-------------------------\r\n"));

    if (this->GetDeviceInfo(&devInfo)) {
        s.print(F("DeviceSerial:    0x"));
        s.print(devInfo.DevID, HEX);
        s.print(F("\r\n"));
    }

    if (this->GetFirmwareInfo(&fwInfo)) {
        s.print(F("FW-Version:      "));
        s.print(fwInfo.FirmwareMayorVersion);
        s.print(F("."));
        s.print(fwInfo.FirmwareMinorVersion);
        s.print(F(" BC: "));
        s.print(fwInfo.BuildCount);
        s.print(F("\r\n"));
        s.print(F("FW-Name:         "));
        s.print((char*)fwInfo.FirmwareName);
        s.print(F("\r\n"));
    }

    if (this->GetDeviceEUI(devEUI)) {
        s.print(F("DeviceEUI:       "));
        for (int i = 0; i < 0x08; i++) {
          if ((uint8_t) devEUI[i] < 0x10) {
              s.print(F("0"));
          }
          s.print((uint8_t) devEUI[i], HEX);
        }
        s.print(F("\r\n"));
    }
    s.print(F("\r\n"));
    return;
}
//! @endcond



/**
 * @brief do a jump start and use OTAA to connect to a Nwk server
 *
 * @param appEUI     pointer to an array containing the AppEUI / JoinEUI data to use
 * @param appKey     pointer to an array containing the AppKey data to use
 */

void WiMODProLink::ConnectViaOTAA(const uint8_t* appEUI, const uint8_t* appKey) {
    TWiMODLORAWAN_NwkStatus_Data   nwkStatus;

    // check if module is de-activated

    this->GetNwkStatus(&nwkStatus);


    if ((nwkStatus.NetworkStatus != LoRaWAN_NwkStatus_Inactive) )
    {
        // the module is already joined / active
        // -> no need to do a manual (re-) join request
        // note: to fore a (re-) join, a deactivate request has to be done first

        return;
    }

    // check if new OTAA parameters are provided
    if (appEUI && appKey) {
        // new OTAA parameters are provided
        // -> prepare to use these parameters

        TWiMODLORAWAN_JoinParams joinParams;

        //setup OTAA parameters
        memcpy(joinParams.JoinEUI, appEUI, 8);
        memcpy(joinParams.AppKey, appKey, 16);

        // transfer parameters to WiMOD module
        this->SetJoinParameter(joinParams);

    } else {
        // no new OTAA parameters are provided
        // try using the previously stored ones from the module
    }

    // send join request; this is an ansynchronous task that may take a while
    this->JoinNetwork();

}



/**
 * @brief Converts a string containing an App EUI string into a given byte array
 *
 * This convinience funtion offers the user the possibilty to use a string
 * containing the AppEUI / JoinEUI as text (e.g. "0x12 34 45 78 9A BC DE f0").
 * The string will be decoded to an byte array for further usage.
 * The string can is interpreted as hex digits with or without a "0x" prefix.
 * Each digit pair must be separated by a space char.
 *
 * @param appEuiStr     String containing the hex coded appEUI / joinEUI
 * @param appEuiArray   array that should store the converted byte values
 * @warning There is no length check of the array. The user is responsible to reserve enough space.
 *
 */
void WiMODProLink::ConvertAppEuiStrToArray(char* appEuiStr, uint8_t* appEuiArray)
{
    StrToIntConverter_convertHexStrToArray(appEuiStr, appEuiArray, 0x08);
}

/**
 * @brief Converts a string containing an App Key string into a given byte array
 *
 * This convinience funtion offers the user the possibilty to use a string
 * containing the AppKey as text (e.g. "0x12 34 45 78 9A BC DE f0 10 20 30 40 50 60 70 80").
 * The string will be decoded to an byte array for further usage.
 * The string can is interpreted as hex digits with or without a "0x" prefix.
 * Each digit pair must be separated by a space char.
 *
 * @param appKeyStr     String containing the hex coded appKey
 * @param appKeyArray   array that should store the converted byte values
 * @warning There is no length check of the array. The user is responsible to reserve enough space.
 *
 */
void WiMODProLink::ConvertAppKeyStrToArray(char* appKeyStr, uint8_t* appKeyArray)
{
    StrToIntConverter_convertHexStrToArray(appKeyStr, appKeyArray, 0x10);
}

/**
 * @brief Converts a string containing an NwkSKey string into a given byte array
 *
 * This convinience funtion offers the user the possibilty to use a string
 * containing the NwkSKey as text (e.g. "0x12 34 45 78 9A BC DE f0 10 20 30 40 50 60 70 80").
 * The string will be decoded to an byte array for further usage.
 * The string can is interpreted as hex digits with or without a "0x" prefix.
 * Each digit pair must be separated by a space char.
 *
 * @param nwkSKeyStr     String containing the hex coded appKey
 * @param nwkSKeyArray   array that should store the converted byte values
 * @warning There is no length check of the array. The user is responsible to reserve enough space.
 *
 */
void WiMODProLink::ConvertNwkSKeyStrToArray(char* nwkSKeyStr, uint8_t* nwkSKeyArray)
{
    StrToIntConverter_convertHexStrToArray(nwkSKeyStr, nwkSKeyArray, 0x10);
}


/**
 * @brief Converts a string containing an AppSKey string into a given byte array
 *
 * This convinience funtion offers the user the possibilty to use a string
 * containing the AppSKey as text (e.g. "0x12 34 45 78 9A BC DE f0 10 20 30 40 50 60 70 80").
 * The string will be decoded to an byte array for further usage.
 * The string can is interpreted as hex digits with or without a "0x" prefix.
 * Each digit pair must be separated by a space char.
 *
 * @param appSKeyStr     String containing the hex coded appKey
 * @param appSKeyArray   array that should store the converted byte values
 * @warning There is no length check of the array. The user is responsible to reserve enough space.
 *
 */
void WiMODProLink::ConvertAppSKeyStrToArray(char* appSKeyStr, uint8_t* appSKeyArray)
{
    StrToIntConverter_convertHexStrToArray(appSKeyStr, appSKeyArray, 0x10);
}


//===============================================================================
//
// DevMgmt
//
//===============================================================================
//-----------------------------------------------------------------------------
/**
 * @brief Ping Cmd - Checks the serial connection to the WiMOD module
 *
 *
 * @see HCI command specification.
 *
 * @param   hciResult       pointer for storing the the local HCI transfer result.
 *                          This is an optional parameter.
 *
 * @param  rspStatus        pointer to store the response code of the WiMOD
 *                          This is an optional parameter.
 *
 * @retval true     if everything is ok
 * @retval false    if something went wrong; see hciResult & rspStatus for details
 *
 * @code
 * if (wimod.Ping()) {
 *  // success ...
 * } else {
 *  // error ...
 * }
 * @endcode
 *
 * OR:
 *
 * @code
 * TWiMODLRResultCodes hciResult;
 *
 * if (!wimod.Ping(&hciResult)) {
 *  // error: check HCI result codes
 *  if (WiMODLR_RESULT_TRANMIT_ERROR == hciResult) {...}
 *  if (WiMODLR_RESULT_NO_RESPONSE   == hciResult) {...}
 * }
 * @endcode
 *
 * OR:
 *
 * @code
 * TWiMODLRResultCodes hciResult;
 * uint8              rspCode;
 *
 * if (!wimod.Ping(&hciResult, &rspCode)) {
 *  // error: check HCI result codes
 *  if (WiMODLR_RESULT_OK == hciResult) {
 *      if (rspCode == DEVMGMT_STATUS_ERROR) {
 *        // operation failed
 *      }
 *      ...
 *  }
 *  ...
 * }
 * @endcode
 *
 */
bool WiMODProLink::Ping(TWiMODLRResultCodes*         hciResult,
                        UINT8*                      rspStatus)
{
    localHciRes = SapDevMgmt.Ping(&localStatusRsp);
    return copyDevMgmtResultInfos(hciResult, rspStatus);
}


//-----------------------------------------------------------------------------
/**
 * @brief Reset Cmd - Reboots the WiMOD module
 *
 *
 * @see HCI command specification.
 *
 * @param   hciResult       pointer for storing the the local HCI transfer result.
 *                          This is an optional parameter.
 *
 * @param  rspStatus        pointer to store the response code of the WiMOD
 *                          This is an optional parameter.
 *
 * @retval true     if everything is ok
 * @retval false    if something went wrong; see hciResult & rspStatus for details
 */
bool WiMODProLink::Reset(TWiMODLRResultCodes*         hciResult,
                         UINT8*                      rspStatus)
{
    localHciRes = SapDevMgmt.Reset(&localStatusRsp);
    return copyDevMgmtResultInfos(hciResult, rspStatus);
}

//-----------------------------------------------------------------------------
/**
 * @brief GetDeviceInfo Cmd - Gets the basic device information of the WiMOD
 *
 *
 * @see HCI command specification.
 *
 * @param   info            pointer for storing the requested information (structure)
 *
 * @param   hciResult       pointer for storing the the local HCI transfer result.
 *                          This is an optional parameter.
 *
 * @param  rspStatus        pointer to store the response code of the WiMOD
 *                          This is an optional parameter.
 *
 * @retval true             if everything was successful
 *
 * @code
 * // create a local variable
 * TWiMODLR_DevMgmt_DevInfo devInfo;
 *
 * // get information of WiMOD
 * wimod.GetDeviceInfo(&devInfo);
 *
 * //access fields of structure
 * printf("ModulType-ID:  %d:", devInfo.ModuleType);
 * printf("DeviceAddress: %x:", devInfo.DevAdr);
 * ...
 * @endcode
 */
bool WiMODProLink::GetDeviceInfo(TWiMODLR_DevMgmt_DevInfoLoRaWan*   info,
                                 TWiMODLRResultCodes*         hciResult,
                                 UINT8*                      rspStatus)
{
    localHciRes = SapDevMgmt.GetDeviceInfo(info, &localStatusRsp);
//    if (info) {
//        localStatusRsp = info->Status;
//    }
    return copyDevMgmtResultInfos(hciResult, rspStatus);
}

//-----------------------------------------------------------------------------
/**
 * @brief GetFirmwareInfo Cmd - Gets the basic information about the firmware of the WiMOD
 *
 *
 * @see HCI command specification.
 *
 * @param   info            pointer for storing the requested information (structure)
 *
 * @param   hciResult       pointer for storing the the local HCI transfer result.
 *                          This is an optional parameter.
 *
 * @param  rspStatus        pointer to store the response code of the WiMOD
 *                          This is an optional parameter.
 *
 * @retval true     if everything is ok
 * @retval false    if something went wrong; see hciResult & rspStatus for details
 *
 * @code
 * // create a local variable
 * TWiMODLR_DevMgmt_FwInfo fwInfo;
 *
 * // get information of WiMOD
 * wimod.GetFirmwareInfo(&fwInfo);
 *
 * //access fields of structure
 * printf("FW-Version:  %d.%d:", fwInfo.FirmwareMayorVersion, fwInfo.FirmwareMinorVersion );
 * printf("FW-Name:     %s:",    fwInfo.FirmwareName);
 * ...
 * @endcode
 */
 bool WiMODProLink::GetFirmwareInfo(TWiMODLR_DevMgmt_FwInfo*  info,
                                 TWiMODLRResultCodes*         hciResult,
                                 UINT8*                      rspStatus)
{
    localHciRes = SapDevMgmt.GetFirmwareInfo(info, &localStatusRsp);
//    if (info) {
//        localStatusRsp = info->Status;
//    }
    return copyDevMgmtResultInfos(hciResult, rspStatus);
}

 //-----------------------------------------------------------------------------
 /**
  * @brief Gets the current RTC data info from WiMOD module
  *
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  * @param rtcTime   Pointer where to store the RTC information
  *                  @see WIMOD_RTC_GET_* Macros for conversation of this value
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * // create a local variable
  * uint32_t timestamp;
  *
  * // get information of WiMOD
  * wimod.GetRtc(&timestamp);
  *
  * //access fields of structure
  * printf("Year : %d:", WIMOD_RTC_GET_YEARS(timestamp));
  * printf("Month: %d:", WIMOD_RTC_GET_MONTHS(timestamp));
  * printf("Day  : %d:", WIMOD_RTC_GET_DAYS(timestamp));
  * printf("Hour : %d:", WIMOD_RTC_GET_HOURS(timestamp));
  * printf("Min  : %d:", WIMOD_RTC_GET_MINUTES(timestamp));
  * printf("Sec  : %d:", WIMOD_RTC_GET_SECONDS(timestamp));
  * ...
  * @endcode
  */
 bool WiMODProLink::GetRtc(UINT32*                    rtcTime,
                          TWiMODLRResultCodes*         hciResult,
                          UINT8*                      rspStatus)
 {
     localHciRes = SapDevMgmt.GetRtc(rtcTime, &localStatusRsp);
     return copyDevMgmtResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Sets the current RTC values to WiMOD module
  *
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  * @param rtcTime   RTC information to setup
  *                  @see WIMOD_RTC_MAKE_DATETIME_U32 Macro for conversation of this value
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * // create a local variable
  * uint32_t timestamp;
  *
  * // convert date/time to timestamp format ( 1st Oct 2016 16:12:55 )
  * timestamp = WIMOD_RTC_MAKE_DATETIME_U32(55, 12, 16, 1, 10, 2016);
  *
  * // set information to WiMOD
  * wimod.SetRtc(timestamp);
  * ...
  * @endcode
  */
 bool WiMODProLink::SetRtc(const UINT32 rtcTime,
                          TWiMODLRResultCodes*         hciResult,
                          UINT8*                      rspStatus)
 {
     localHciRes = SapDevMgmt.SetRtc(rtcTime, &localStatusRsp);
     return copyDevMgmtResultInfos(hciResult, rspStatus);
 }



 //-----------------------------------------------------------------------------
 /**
  * @brief Sets and enables the RTC alarm feature of the WiMOD
  *
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  * @param rtcAlarm   Pointer to a structure containing the RTC alarm related
  *                   information
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="SetRtcAlarm(rtcAlarmData)"];
  * ...;
  * --- [label="RTC triggers alarm"];
  * UserApp<<=WiMOD [label="myRtcAlarmCallback()"];
  * UserApp->UserApp [label="start triggered processing"];
  * \endmsc
  *
  *
  * @code
  * // create a local variable
  * TWiMODLR_DevMgmt_RtcAlarm rtcAlarm;
  *
  * // setup RTC Alarm
  * rtcAlarm.Options = RTC_Alarm_Single;  // single, non repeated alarm
  * rtcAlarm.Hour    = 13;                // alarm at 13:45:20
  * rtcAlarm.Minutes = 32;
  * rtcAlarm.Seconds = 20;
  *
  * // set information of WiMOD
  * wimod.SetRtcAlarm(&rtcAlarm);
  * ...
  * // wait for alarm to occur
  * @endcode
  */
 bool WiMODProLink::SetRtcAlarm(const TWiMODLR_DevMgmt_RtcAlarm* rtcAlarm,
                 TWiMODLRResultCodes*               hciResult,
                 UINT8*                         rspStatus)
 {
   localHciRes = SapDevMgmt.SetRtcAlarm(rtcAlarm, &localStatusRsp);
   return copyDevMgmtResultInfos(hciResult, rspStatus);
 }


 //-----------------------------------------------------------------------------
 /**
  * @brief Gets information about the RTC alarm feature of the WiMOD
  *
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  * @param rtcAlarm   Pointer to a structure where to store the RTC alarm related
  *                   information
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * // create a local variable
  * TWiMODLR_DevMgmt_RtcAlarm rtcAlarm;
  *
  * // get information of WiMOD
  * wimod.GetRtcAlarm(&rtcAlarm);
  * ...
  * // access values
  * if (rtcAlarm.AlarmStatus == RTC_Alarm_Alarm_Set) {
  *  printf("Alarm is active");
  *  ...
  * }
  * ...
  * @endcode
  */
 bool WiMODProLink::GetRtcAlarm(TWiMODLR_DevMgmt_RtcAlarm*       rtcAlarm,
                 TWiMODLRResultCodes*                hciResult,
                 UINT8*                          rspStatus)
 {
   localHciRes = SapDevMgmt.GetRtcAlarm(rtcAlarm, &localStatusRsp);
   return copyDevMgmtResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Clears pending RTC Alarms of the WiMOD
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * // clear a pending RTC alarm of WiMOD
  * wimod.ClearRtcAlarm();
  * ...
  * @endcode
  */
 bool WiMODProLink::ClearRtcAlarm(TWiMODLRResultCodes*           hciResult,
                 UINT8*                          rspStatus)
 {
   localHciRes = SapDevMgmt.ClearRtcAlarm(&localStatusRsp);
   return copyDevMgmtResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the PowerUp Indication - optional -
  *
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  * @param cb        Pointer a callback function
  *                  @see TDevMgmtPowerUpCallback for details
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="RegisterPowerUpIndicationClient(clientCB)"];
  * ...;
  * UserApp<<=WiMOD [label="PowerUpCallback()"];
  * \endmsc
  *
  * @code
  * // user defined callback function
  * void myPowerUpCallback(void) {
  *   // WiMOD just powered up
  *  ...
  * }
  *
  * void setup() {
  *  ...
  *  // "connect" the user defined to callback to the WiMOD callback feature
  *  wimod.RegisterPowerUpIndicationClient(myPowerUpCallback);
  *  ...
  * }
  * @endcode
  */
 void WiMODProLink::RegisterPowerUpIndicationClient(TDevMgmtPowerUpCallback cb)
 {
     SapDevMgmt.RegisterPowerUpIndicationClient(cb);
 }


 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the RTC Alarm Indication - optional -
  *
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  * @param cb        Pointer a callback function
  *                  @see TDevMgmtRtcAlarmCallback for details
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="RegisterRtcAlarmIndicationClient(clientCB)"];
  * ...;
  * UserApp<<=WiMOD [label="RtcAlarmCallback()"];
  * \endmsc
  *
  * @code
  * // user defined callback function
  * void myRtcAlarmCallback(void) {
  *  // RTC Alarm has just been triggered
  *  ...
  * }
  *
  * void setup() {
  *  ...
  *  // "connect" the user defined to callback to the WiMOD callback feature
  *  wimod.RegisterRtcAlarmIndicationClient(myRtcAlarmCallback);
  *  ...
  * }
  * @endcode
  *
  */
 void WiMODProLink::RegisterRtcAlarmIndicationClient(TDevMgmtRtcAlarmCallback cb)
 {
   SapDevMgmt.RegisterRtcAlarmIndicationClient(cb);
 }


 //-----------------------------------------------------------------------------
 /**
  * @brief Gets the current HCI configuration of the WiMOD
  *
  *
  * @see HCI documentation and feature specification for details
  *
  * @param hciConfig   Pointer to a structure where to store the HCI config related
  *                   information
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * // create a local variable
  * TWiMODLR_DevMgmt_HciConfig hciConfig;
  *
  * // get information of WiMOD
  * wimod.GetHciConfig(&hciConfig);
  * ...
  * // access values
  * if (hciConfig.NumWakeUpChars == 40) {
  *  ...
  * }
  * ...
  * @endcode
  */
 bool WiMODProLink::GetHciConfig(TWiMODLR_DevMgmt_HciConfig*     hciConfig,
                                 TWiMODLRResultCodes*            hciResult,
                                 UINT8*                          rspStatus)
 {
     localHciRes = SapDevMgmt.GetHCIConfig(hciConfig, &localStatusRsp);
     return copyDevMgmtResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Sets a new HCI configuration of the WiMOD
  *
  *
  * @see HCI documentation and feature specification for details
  *
  * @warning Changing the Baudrate applies instandly afer the command is executed!
  *
  * @param hciConfig   Pointer to a structure where to store the HCI config related
  *                   information
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * // create a local variable
  * TWiMODLR_DevMgmt_HciConfig hciConfig;
  *
  * // create new config values
  * hciConfig.BaudrateID = WimodHciBaudrate_57600;
  * ...
  *
  * // set information of WiMOD
  * wimod.GetHciConfig(&hciConfig);
  * ...
  * @endcode
  */
 bool WiMODProLink::SetHciConfig(TWiMODLR_DevMgmt_HciConfig&       hciConfig,
                                 TWiMODLRResultCodes*              hciResult,
                                 UINT8*                            rspStatus)
 {
     localHciRes = SapDevMgmt.SetHCIConfig(hciConfig, &localStatusRsp);
     return copyDevMgmtResultInfos(hciResult, rspStatus);
 }



//-----------------------------------------------------------------------------
/**
* @brief Gets the active Radio Stack Mode of the WiMOD (only ProLink firmware)
*
*
* @see HCI documentation and feature specification for details
*
*
* @param stackMode  pointer where to store the current stack mode information
*
* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*
* @code
* // create a local variable
* TRadioStack_Mode mode;
*
* ...
*
* // reqeust the information of WiMOD
* wimod.GetRadioStack(&mode);
*
* if (mode == RadioStack_LoRaWAN) {
*   // the modem is in LoRaWAN mode
*   ...
* } else {
*   // the modem is in proprietary mode
*   ...
* }
* ...
* @endcode
*/
bool WiMODProLink::GetRadioStack(TRadioStack_Mode*     stackMode,
                                  TWiMODLRResultCodes*  hciResult,
                                  UINT8*                rspStatus)
{
     localHciRes = SapDevMgmt.GetRadioStack(stackMode, &localStatusRsp);
     return copyDevMgmtResultInfos(hciResult, rspStatus);
}

//-----------------------------------------------------------------------------
/**
* @brief Sets the active Radio Stack Mode of the WiMOD (only ProLink firmware)
*
*
* @see HCI documentation and feature specification for details
*
*
* @param stackMode  the new stack mode to be used by the WiMOD
*
* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*
* @code
*
* ...
*
* // switch to LoRaWAN mode
* wimod.SetRadioStack(RadioStack_LoRaWAN);
*
* ...
* @endcode
*/
bool WiMODProLink::SetRadioStack(const TRadioStack_Mode& stackMode,
                                   TWiMODLRResultCodes*  hciResult,
                                   UINT8*                rspStatus)
{
    localHciRes = SapDevMgmt.SetRadioStack(stackMode, &localStatusRsp);
    return copyDevMgmtResultInfos(hciResult, rspStatus);
}



//-----------------------------------------------------------------------------
/**
* @brief Sets the common Device config features of the WiMOD (only ProLink firmware)
*
*
* @see HCI documentation and feature specification for details
*
*
* @param config   The common config options used by all stacks of the WiMOD
*
* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*
* @code
* // create a local variable
* TProLinkDeviceConfig config;
*
* ...
* // configure wanted features
* config.PowerSaving = 1;
* config.MiscOptions |= PROLINK_DEVICE_CFG_MISC_HCI_PWR_UP_IND_ENABLED
*
* // setup the common settings for all stacks of the WiMOD
* wimod.SetDeviceConfig(config);
* ...
* @endcode
*/

bool WiMODProLink::SetDeviceConfig(const TProLinkDeviceConfig& config,
                                    TWiMODLRResultCodes*  hciResult,
                                    UINT8*                rspStatus)
{
    localHciRes = SapDevMgmt.SetDeviceConfig(config, &localStatusRsp);
    return copyDevMgmtResultInfos(hciResult, rspStatus);

}

//-----------------------------------------------------------------------------
/**
* @brief Gets the common Device config of the WiMOD (only ProLink firmware)
*
*
* @see HCI documentation and feature specification for details
*
*
* @param config   The common config options used by all stacks of the WiMOD
*
* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*
* @code
* // create a local variable
* TProLinkDeviceConfig config;
*
* ...
*
* // reqeust the information of WiMOD
* wimod.GetDeviceConfig(&config);
*
* // check the enabled features
* if (config.PowerSavingMode == 1) {
*   // automatic power saving mode is on
*   // a SLIP wakeup sequence is needed for serial communication
*   ....
* }
* if (mode.MiscOptions & PROLINK_DEVICE_CFG_MISC_HCI_PWR_UP_IND_ENABLED) {
*   // the WiMOD will generate a PowerUp indication on PowerUp
*   ....
* }
* ...
* @endcode
*/
bool WiMODProLink::GetDeviceConfig(TProLinkDeviceConfig* config,
                                  TWiMODLRResultCodes*  hciResult,
                                  UINT8*                rspStatus)
{
     localHciRes = SapDevMgmt.GetDeviceConfig(config, &localStatusRsp);
     return copyDevMgmtResultInfos(hciResult, rspStatus);
}


//-----------------------------------------------------------------------------
/**
 * @brief Resets the settings about the common stack features of the WiMOD module (ProLink firmware)
 *
 *
 * @see HCI command specification.
 *
 * @param   hciResult       pointer for storing the the local HCI transfer result.
 *                          This is an optional parameter.
 *
 * @param  rspStatus        pointer to store the response code of the WiMOD
 *                          This is an optional parameter.
 *
 * @retval true     if everything is ok
 * @retval false    if something went wrong; see hciResult & rspStatus for details
 */
bool WiMODProLink::ResetDeviceConfig(TWiMODLRResultCodes*  hciResult,
                                     UINT8*                rspStatus)
{
    localHciRes = SapDevMgmt.ResetDeviceConfig(&localStatusRsp);
    return copyDevMgmtResultInfos(hciResult, rspStatus);
}


//-----------------------------------------------------------------------------
/**
* @brief GetDeviceStatus Cmd - Gets the basic information about the device status of the WiMOD
*
*
* @see HCI command specification.
*
* @param   info            pointer for storing the requested information (structure)
*
* @param   hciResult       pointer for storing the the local HCI transfer result.
*                          This is an optional parameter.
*
* @param  rspStatus        pointer to store the response code of the WiMOD
*                          This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*
* @code
* // create a local variable
* TProLinkDeviceStatus devStatus;
*
* // get information of WiMOD
* wimod.GetDeviceStatus(&devStatus);
*
* //access fields of structure
* printf("Sys-SysTicks:           %d:", sysStatus.SysTickCounter);
* printf("LoRaWAN UData packets:  %d:", sysStatus.LoRaWAN_TxUDataPackets);
* printf("LRBASE Tx packets:      %d:", sysStatus.LRBASE_TxPackets);
*
* ...
* @endcode
*/
bool WiMODProLink::GetDeviceStatus(TProLinkDeviceStatus*  devStatus,
                                    TWiMODLRResultCodes*  hciResult,
                                    UINT8*                rspStatus)
{
    localHciRes = SapDevMgmt.GetDeviceStatus(devStatus, &localStatusRsp);
    return copyDevMgmtResultInfos(hciResult, rspStatus);
}

//===============================================================================
//
// LoRaWAN
//
//===============================================================================

 //-----------------------------------------------------------------------------
 /**
  * @brief Activates the device via the ABP procedure
  *
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  * @param activationData   structure holding the necessary parameters
  *
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="ActivateDevice(activationData)"];
  * UserApp<<WiMOD  [label="Activation response"];
  * ...;
  * --- [label = "time to transmit data"];
  * UserApp=>WiMOD [label="SendUData(data)"];
  * \endmsc
  *
  * @code
  * // ABP data
  * const uint32_t  DEV_ADR = 0x22;
  * const char NWKSKEY[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0f, 0x10 };
  * const char APPSKEY[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0f, 0x10 };
  *
  * // create a local variable
  * TWiMODLORAWAN_ActivateDeviceData activationData;
  *
  * void setup() {
  *  //setup data
  *  activationData.DeviceAddress = DEV_ADR;
  *  memcpy(activationData.NwkSKey, NWKSKEY, 16);
  *  memcpy(activationData.AppSKey, APPSKEY, 16);
  *
  *  // activate device
  *  if (wimod.ActivateDevice(activationData)) {
  *      // ABP procedure done
  *      ...
  *  } else {
  *      // Error executing ABP join request
  *      ...
  *  }
  * ...
  * @endcode
  */
 bool WiMODProLink::ActivateDevice(TWiMODLORAWAN_ActivateDeviceData& activationData,
         TWiMODLRResultCodes*         hciResult,
         UINT8*                      rspStatus)
 {

     localHciRes = SapLoRaWan.ActivateDevice(activationData, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }


 //-----------------------------------------------------------------------------
 /**
  * @brief Re-Activates the device via the ABP procedure
  *
  * In case the device has been previously activated (e.g. during manufacturing)
  * the user does not know the security keys.
  * In this case a re-activation procedure must be used in order to use the
  * stored values. (For ABP ONLY!)
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  * @param devAdr   pointer where the store the "received" device address
  *
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * \msc
  * UserApp,WiMOD;
  * |||;
  * UserApp note WiMOD [label="Device was (pre) activated in the past; ABP ONLY"];
  * ...;
  * UserApp=>WiMOD  [label="ReactivateDevice(devAdr)"];
  * UserApp<<WiMOD  [label="Reactivation response"];
  * ...;
  * --- [label = "time to transmit data"];
  * UserApp=>WiMOD [label="SendUData(data)"];
  * \endmsc
  *
  * @code
  * // ABP data
  * const uint32_t  DEV_ADR = 0x22;
  *
  * // security keys are not known the user
  *
  *
  * void setup() {
  *  // local variable
  *  uint32_t devAddr = DEV_ADR;
  *
  *  // activate device
  *  if (wimod.ReactivateDevice(activationData)) {
  *      // ABP procedure done
  *      ...
  *  } else {
  *      // Error executing ABP join request
  *      ...
  *  }
  * ...
  * @endcode
  */
 bool WiMODProLink::ReactivateDevice(UINT32* devAdr,
         TWiMODLRResultCodes*         hciResult,
         UINT8*                      rspStatus)
 {

     localHciRes = SapLoRaWan.ReactivateDevice(devAdr, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Sets the parameters used for the OTAA activation procedure
  *
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  * @param joinParams   structure holding the necessary parameters
  *
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * // OTAA data
  * const char JOINEUI[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 };
  * const char APPKEY[]  = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0f, 0x10 };
  *
  * void setup() {
  *  // local variable
  *  TWiMODLORAWAN_JoinParams joinParams;
  *
  *  // setup parameters
  *  memcpy(joinParams.JoinEUI, JOINEUI, 8);
  *  memcpy(joinParams.AppKey, APPKEY, 16);
  *
  *  // transfer parameters to WiMOD
  *  wimod.SetJoinParameter(joinParams);
  *  ...
  * @endcode
  */
 bool WiMODProLink::SetJoinParameter(TWiMODLORAWAN_JoinParams& joinParams,
         TWiMODLRResultCodes*         hciResult,
         UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.SetJoinParameter(joinParams, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Start joining the network via the OTAA procedure. Asynchronous process
  *
  * This functions starts an asynchronous process of joining to a network.
  * It will take a time until a (final) result is ready. Therefore the
  * callback interface (e.g. RegisterJoinedNwkIndicationClient) should be used.
  *
  * @see TWiMODLRResultCodes for interpretation of the values
  *
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * \msc
  * UserApp,WiMOD,Server;
  * |||;
  * UserApp=>WiMOD  [label="RegisterJoinedNwkIndicationClient(myJoinCallback)"];
  * UserApp=>WiMOD  [label="SetJoinParameter(joinParams)"];
  * UserApp=>WiMOD  [label="JoinNetwork()"];
  * WiMOD->Server   [label="JoinNwk Req."];
  * UserApp<<WiMOD  [label="JoinTxInd [optional]"];
  * ...;
  * WiMOD<-Server   [label="JoinNwk Rsp"];
  * UserApp<<=WiMOD [label="JoinedNwkIndication()"];
  * ...;
  * --- [label = "time to transmit data"];
  * UserApp=>WiMOD [label="SendUData(data)"];
  * \endmsc
  *
  * @code
  * void myNwkJoinedCallback(TWiMODLR_HCIMessage& rxMsg) {
  *  // handle and check the given rsp data of the server
  *  ...
  * }
  *
  * void setup() {
  *  ...
  *  // setup OTAA / join related parameters and transfer it to WiMOD
  *  wimod.SetJoinParameter(joinParams);
  *
  *  // register joined nwk callback
  *  wimod.RegisterJoinedNwkIndicationClient(myNwkJoinedCallback);
  *
  *  // start OTAA procedure by sending a join request
  *  if (wimod.JoinNetwork()) {
  *      // OK procedure has been started
  *      // wait for callback indicating status of procedure
  *  } else {
  *      // error
  *      ...
  *  }
  * ...
  * @endcode
  */
 bool WiMODProLink::JoinNetwork(
         TWiMODLRResultCodes*         hciResult,
         UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.JoinNetwork(&localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "TX Join Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  *
  *
  * @code
  * void myJoinReqTxCallback(TWiMODLR_HCIMessage& rxMsg) {
  *  // handle and check the given rsp data of the server
  *  TWiMODLORAWAN_TxIndData txData;
  *  wimod.convert(rxMsg, &txData);
  *  printf("joining attempt: %d", txData.NumTxPackets);
  *  ...
  * }
  *
  * void setup() {
  *  ...
  *  // register joined nwk callback
  *  wimod.RegisterJoinTxIndicationClient(myJoinReqTxCallback);
  *  ...
  * }
  * @endcode
  */
 void WiMODProLink::RegisterJoinTxIndicationClient(TJoinTxIndicationCallback cb)
 {
     SapLoRaWan.RegisterJoinTxIndicationClient(cb);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Convert a received low level HCI-Msg to a high-level Rx Data structure
  *
  * This function should be used by the Rx Data Indication Callback functions
  * prior processing the received data message.
  *
  * @param   RxMsg       Reference to low-level HCI message.
  *                      @warning DO NOT MANIPULATE THESE VALUES !!!
  *
  * @param   loraWanRxData Pointer to the buffer where to store the received data
  *
  * @retval true     if the conversion was successful
  *
  * \msc
  * UserApp,WiMOD,Server;
  * |||;
  * UserApp->WiMOD  [label="RegisterRxUDataIndicationClient(myNewDataCallback)"];
  * ...;
  * WiMOD<-Server   [label="new (U)Data"];
  * UserApp<<=WiMOD [label="myNewDataCallback(LowLevelData)"];
  * UserApp->WiMOD  [label="convert(LowLevelData, RXmsg)"];
  * UserApp<<WiMOD  ;
  * UserApp->UserApp [label="further processing"];
  * ...;
  * \endmsc
  *
  * @code
  * void onRxData(TWiMODLR_HCIMessage& rxMsg) {
  *  TWiMODLORAWAN_RX_Data radioRxMsg;
  *
  *  // convert/copy the raw message to RX radio buffer
  *  if (wimod.convert(rxMsg, &radioRxMsg)) {
  *      // OK, process RX data
  *      ...
  *  }
  * }
  * ...
  * void setup() {
  *  ...
  *  // setup user callbacks for RX data events
  *  wimod.RegisterRxCDataIndicationClient(onRxData);
  *  wimod.RegisterRxUDataIndicationClient(onRxData);
  * }
  * ...
  *
  * @endcode
  */
 bool WiMODProLink::convert(TWiMODLR_HCIMessage& RxMsg,
         TWiMODLORAWAN_RX_Data* loraWanRxData)
 {
     return SapLoRaWan.convert(RxMsg, loraWanRxData);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Convert a received low level HCI-Msg to a high-level tx ind structure
  *
  * This function should be used by the Tx Data Indication Callback functions
  * prior processing the received data message.
  *
  * @param   RxMsg       Reference to low-level HCI message.
  *                      @warning DO NOT MANIPULATE THESE VALUES !!!
  *
  * @param   sendIndData Pointer to the buffer where to store the received data
  *
  * @retval true     if the conversion was successful
  *
  * \msc
  * UserApp,WiMOD,Server;
  * |||;
  * UserApp->WiMOD  [label="RegisterTxUDataIndicationClient(myTxInd)"];
  * UserApp->WiMOD  [label="RegisterTxCDataIndicationClient(myTxInd)"];
  * ...;
  * UserApp->WiMOD  [label="SendUData()"];
  * WiMOD->Server   [label="transfer data"];
  * UserApp<<=WiMOD [label="myTxInd(LowLevelData)"];
  * UserApp->WiMOD  [label="convert(LowLevelData, txData)"];
  * ...;
  * UserApp<<WiMOD  ;
  * UserApp->UserApp [label="further processing"];
  * \endmsc
  *
  * @code
  * void myTxInd(TWiMODLR_HCIMessage& rxMsg) {
  *  TWiMODLORAWAN_TxIndData txData;
  *
  *  // convert/copy the raw message to tx indication data
  *  if (wimod.convert(rxMsg, &txData)) {
  *      // OK, process data
  *      ...
  *  }
  * }
  * ...
  * void setup() {
  *  ...
  *  // setup user callbacks for TX indication events
  *  wimod.RegisterTxUDataIndicationClient(myTxInd);
  *  wimod.RegisterTxCDataIndicationClient(myTxInd);
  * }
  * ...
  *
  * @endcode
  */
 bool WiMODProLink::convert(TWiMODLR_HCIMessage& RxMsg,
         TWiMODLORAWAN_TxIndData* sendIndData)
 {
     return SapLoRaWan.convert(RxMsg, sendIndData);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Convert a received low level HCI-Msg to a high-level MAC-Cmd structure
  *
  * This function should be used by the Rx Mac Cmd Indication Callback function
  * prior processing the received data message.
  *
  * @param   RxMsg       Reference to low-level HCI message.
  *                      @warning DO NOT MANIPULATE THESE VALUES !!!
  *
  * @param   loraWanMacCmdData Pointer to the buffer where to store the received data
  *
  * @retval true     if the conversion was successful
  *
  * \msc
  * UserApp,WiMOD,Server;
  * |||;
  * UserApp->WiMOD  [label="RegisterRxMacCmdIndicationClient(myMacCmdInd)"];
  * ...;
  * WiMOD<-Server   [label="MAC Cmd + data"];
  * UserApp<<=WiMOD [label="myMacCmdInd(LowLevelData)"];
  * UserApp->WiMOD  [label="convert(LowLevelData, macData)"];
  * ...;
  * UserApp<<WiMOD  ;
  * UserApp->UserApp [label="further processing"];
  * \endmsc
  *
  * @code
  * void myMacCmdInd(TWiMODLR_HCIMessage& rxMsg) {
  *  TWiMODLORAWAN_RX_MacCmdData macData;
  *
  *  // convert/copy the raw message to MAC cmd indication data
  *  if (wimod.convert(rxMsg, &macData)) {
  *      // OK, process data
  *      ...
  *  }
  * }
  * ...
  * void setup() {
  *  ...
  *  // setup user callback for MAC cmd indication events
  *  wimod.RegisterRxMacCmdIndicationClient(myMacCmdInd);
  * }
  * ...
  *
  * @endcode
  */
 bool WiMODProLink::convert(TWiMODLR_HCIMessage& RxMsg,
         TWiMODLORAWAN_RX_MacCmdData* loraWanMacCmdData)
 {
     return SapLoRaWan.convert(RxMsg, loraWanMacCmdData);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Convert a received low level HCI-Msg to a high-level NwkJoined structure
  *
  * This function should be used by the JoinedNwk Indication Callback function
  * prior processing the received data message.
  *
  * @param   RxMsg       Reference to low-level HCI message.
  *                      @warning DO NOT MANIPULATE THESE VALUES !!!
  *
  * @param   joinedNwkData Pointer to the buffer where to store the received data
  *
  * @retval true     if the conversion was successful
  *
  * \msc
  * UserApp,WiMOD,Server;
  * |||;
  * UserApp->WiMOD  [label="RegisterJoinedNwkIndicationClient(myJoinedNwkInd)"];
  * ...;
  * UserApp=>WiMOD  [label="SetJoinParameter(params)"];
  * UserApp=>WiMOD  [label="JoinNetwork()"];
  * WiMOD->Server   [label="Start OTAA procedure"];
  * ...;
  * ...;
  * WiMOD<-Server   [label="JoinNwkIndication"];
  * UserApp<<=WiMOD [label="myJoinedNwkInd(LowLevelData)"];
  * UserApp->WiMOD  [label="convert(LowLevelData, joinData)"];
  * ...;
  * UserApp<<WiMOD  ;
  * UserApp->UserApp [label="further processing"];
  * \endmsc
  *
  * @code
  * void myJoinedNwkInd(TWiMODLR_HCIMessage& rxMsg) {
  *  TWiMODLORAWAN_RX_JoinedNwkData joinData;
  *
  *  // convert/copy the raw message to a joined nwk indication data structure
  *  if (wimod.convert(rxMsg, &joinData)) {
  *      // OK, process data
  *      ...
  *  }
  * }
  * ...
  * void setup() {
  *  ...
  *  // setup user callback for joined network indication (for OTAA procedure)
  *  wimod.RegisterJoinedNwkIndicationClient(myJoinedNwkInd);
  * }
  * ...
  *
  * @endcode
  */
 bool WiMODProLink::convert(TWiMODLR_HCIMessage& RxMsg,
         TWiMODLORAWAN_RX_JoinedNwkData* joinedNwkData)
 {
     return SapLoRaWan.convert(RxMsg, joinedNwkData);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Convert a received low level HCI-Msg to a high-level AckData structure
  *
  * This function should be used by the Rx Ack Indication Callback function
  * prior processing the received data message.
  *
  * @param   RxMsg       Reference to low-level HCI message.
  *                      @warning DO NOT MANIPULATE THESE VALUES !!!
  *
  * @param   ackData     Pointer to the buffer where to store the received data
  *
  * @retval true     if the conversion was successful
  *
  * \msc
  * UserApp,WiMOD,Server;
  * |||;
  * UserApp->WiMOD  [label="RegisterRxAckIndicationClient(myRxAckInd)"];
  * ...;
  * UserApp->WiMOD  [label="SendCData(data)"];
  * WiMOD->Server   [label="transmit C data"];
  * WiMOD<-Server   [label="ACK"];
  * UserApp<<=WiMOD [label="myRxAckInd(LowLevelData)"];
  * UserApp->WiMOD  [label="convert(LowLevelData, rxAckData)"];
  * ...;
  * UserApp<<WiMOD  ;
  * UserApp->UserApp [label="further processing"];
  * \endmsc
  *
  * @code
  * void myRxAckInd(TWiMODLR_HCIMessage& rxMsg) {
  *  TWiMODLORAWAN_RX_ACK_Data rxAckData;
  *
  *  // convert/copy the raw message to a RX ACK data structure
  *  if (wimod.convert(rxMsg, &rxAckData)) {
  *      // OK, process data
  *      ...
  *  }
  * }
  * ...
  * void setup() {
  *  ...
  *  // setup user callback for receiving RX ACK indications
  *  wimod.RegisterRxAckIndicationClient(myRxAckInd);
  * }
  * ...
  *
  * @endcode
  */
 bool WiMODProLink::convert(TWiMODLR_HCIMessage& RxMsg,
         TWiMODLORAWAN_RX_ACK_Data* ackData)
 {
     return SapLoRaWan.convert(RxMsg, ackData);
 }


 //-----------------------------------------------------------------------------
 /**
  * @brief Convert a received low level HCI-Msg to a high-level NoData structure
  *
  * This function should be used by the NoData Indication Callback function
  * prior processing the received data message.
  *
  * @param   RxMsg       Reference to low-level HCI message.
  *                      @warning DO NOT MANIPULATE THESE VALUES !!!
  *
  * @param   info      Pointer to the buffer where to store the received information
  *
  * @retval true     if the conversion was successful
  *
  *
  * \msc
  * UserApp,WiMOD,Server;
  * |||;
  * UserApp->WiMOD  [label="RegisterNoDataIndicationClient(myNoDataInd)"];
  * ...;
  * UserApp->WiMOD  [label="SendUData(data)"];
  * WiMOD->Server   [label="transmit U data"];
  * |||;
  * ...;
  * |||;
  * UserApp<<=WiMOD [label="myNoDataInd(LowLevelData)"];
  * UserApp->WiMOD  [label="convert(LowLevelData, info)"];
  * ...;
  * UserApp<<WiMOD  ;
  * UserApp->UserApp [label="further processing"];
  * \endmsc
  *
  */

 bool WiMODProLink::convert(TWiMODLR_HCIMessage& RxMsg,
     TWiMODLORAWAN_NoData_Data* info)
 {
   return SapLoRaWan.convert(RxMsg, info);
 }




 //-----------------------------------------------------------------------------
 /**
  * @brief Convert a received low level HCI-Msg to a high-level RadioLink-Msg
  *
  * This function should be used by the RxUData / RxCData callback functions
  * prior processing the received data message.
  *
  * @param   RxMsg       Reference to low-level HCI message.
  *                      @warning DO NOT MANIPULATE THESE VALUES !!!
  *
  * @param   radioLinkMsg Pointer to the buffer where to store the received data
  *
  * @retval true     if the conversion was successful
  *
  *
  * \msc
  * UserApp,WiMOD,RemotePeer;
  * ... ;
  * UserApp=>WiMOD     [label="RegisterUDataRxClient(myRxDataInd)"];
  * ...;
  * --- [label="Peer device want to transfer data"];
  * WiMOD<-RemotePeer  [label="transfer data"];
  * --- [label="if ack callback is registered"];
  * UserApp << WiMOD [label="myRxDataInd()"];
  * UserApp->UserApp [label="further processing"];
  * ...;
  *
  * \endmsc
  *
  * @code
  * // global buffer for incoming messages
  * TWiMODLR_RadioLink_Msg radioRxMsg;
  *
  * void myRxDataInd(TWiMODLR_HCIMessage& rxMsg) {
  *    // convert/copy the raw message to RX radio buffer
  *    if (wimod.convert(rxMsg, &radioRxMsg)) {
  *        // access the radioRxMsg fields
  *
  *        // radioRxMsg.Length
  *        // radioRxMsg.Payload
  *    ...
  *    }
  * }
  *...
  *
  * void setup() {
  *    ...
  *    // init the communication stack
  *    wimod.begin();
  *
  *     // register callbacks for incoming RF messages
  *    wimod.RegisterUDataRxClient(myRxDataInd);
  *    ...
  * }
  * @endcode
  */
 bool WiMODProLink::convert(TWiMODLR_HCIMessage&    RxMsg,
                           TWiMODLR_RadioLink_Msg* radioLinkMsg) {
     return SapRadioLink.convert(RxMsg, radioLinkMsg);
 }


 //-----------------------------------------------------------------------------
 /**
  * @brief Convert a received low level HCI-Msg to a high-level UDataTx Info
  *
  * This function should be used by the Tx-U-Data Indication Callback functions
  * prior processing the received data message.
  *
  * @param   RxMsg       Reference to low-level HCI message.
  *                      @warning DO NOT MANIPULATE THESE VALUES !!!
  *
  * @param   uDataTxInfo Pointer to the buffer where to store the received data
  *
  * @retval true     if the conversion was successful
  *
  * \msc
  * UserApp,WiMOD,RemotePeer;
  * ... ;
  * UserApp=>WiMOD     [label="RegisterRadioLinkTxUDataIndicationClient(myTxUDataInd)"];
  * ...;
  * UserApp->WiMOD     [label="SendUData(data)"];
  * WiMOD->RemotePeer  [label="transfer data"];
  * --- [label="if callback is registered"];
  * UserApp << WiMOD   [label="myTxUDataInd()"];
  * UserApp->UserApp [label="further processing"];
  * ...;
  *
  * \endmsc
  *
  * @code
  * // global buffer for indication that UData has been send
  * TWiMODLR_RadioLink_UdataInd txDataMsg;
  *
  * void myTxUDataInd(TWiMODLR_HCIMessage& rxMsg) {
  *    // convert/copy the raw message to RX radio buffer
  *    if (wimod.convert(rxMsg, &txDataMsg)) {
  *        // access the fields folding information about the transmission
  *
  *        // txDataMsg.TxEventCounter
  *    ...
  *    }
  * }
  *...
  *
  * void setup() {
  *    ...
  *    // init the communication stack
  *    wimod.begin();
  *
  *     // register callback
  *    wimod.RegisterRadioLinkTxUDataIndicationClient(myTxUDataInd);
  *    ...
  * }
  * @endcode
  *
  */

 bool WiMODProLink::convert(TWiMODLR_HCIMessage& RxMsg,
                             TWiMODLR_RadioLink_UdataInd* uDataTxInfo) {
     return SapRadioLink.convert(RxMsg, uDataTxInfo);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "TX Join Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  *
  * \msc
  * UserApp,WiMOD,Server;
  * |||;
  * UserApp->WiMOD  [label="RegisterNoDataIndicationClient(myNoDataInd)"];
  * ...;
  * --- [label="timeout example for TX C-Data"];
  * UserApp->WiMOD  [label="SendCData(data)"];
  * WiMOD->Server   [label="transmit C data"];
  * WiMOD x- Server [label="ACK"];
  * UserApp<<=WiMOD [label="myNoDataInd()"];
  * UserApp->UserApp [label="further processing"];
  * ...;
  * \endmsc
  *
  * @code
  * void myNoDataInd() {
  *  // no data has been received; timeout occurred.?
  *  ...
  * }
  * ...
  * void setup() {
  *  ...
  *  // setup user callback for "no data rx" indications
  *  wimod.RegisterNoDataIndicationClient(myNoDataInd);
  * }
  * ...
  * @endcode
  */
 void WiMODProLink::RegisterNoDataIndicationClient(TNoDataIndicationCallback cb)
 {
     SapLoRaWan.RegisterNoDataIndicationClient(cb);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "TX C-Data Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  * \msc
  * UserApp,WiMOD,Server;
  * |||;
  * UserApp=>WiMOD  [label="RegisterTxCDataIndicationClient(myTxInd)"];
  * ...;
  * UserApp->WiMOD  [label="SendCData(data)"];
  * WiMOD->Server   [label="transfer data"];
  * UserApp<<=WiMOD [label="myTxInd(LowLevelData)"];
  * UserApp->WiMOD  [label="convert(LowLevelData, txIndData)"];
  * UserApp<<WiMOD  ;
  * UserApp->UserApp [label="further processing"];
  * ...;
  * \endmsc
  *
  * @code
  * void myTxInd(TWiMODLR_HCIMessage& rxMsg) {
  *  TWiMODLORAWAN_TxIndData txData;
  *
  *  // convert/copy the raw message to tx indication data
  *  if (wimod.convert(rxMsg, &txData)) {
  *      // OK, process data
  *      ...
  *  }
  * }
  * ...
  * void setup() {
  *  ...
  *  // setup user callback(s) for TX indication events
  *  wimod.RegisterTxCDataIndicationClient(myTxInd);
  * }
  * ...
  * @endcode
  */
 void WiMODProLink::RegisterTxCDataIndicationClient(TTxCDataIndicationCallback cb)
 {
     SapLoRaWan.RegisterTxCDataIndicationClient(cb);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "TX U Data Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  *
  * \msc
  * UserApp,WiMOD,Server;
  * |||;
  * UserApp=>WiMOD  [label="RegisterTxUDataIndicationClient(myTxInd)"];
  * ...;
  * UserApp->WiMOD  [label="SendUData(data)"];
  * WiMOD->Server   [label="transfer data"];
  * UserApp<<=WiMOD [label="myTxInd(LowLevelData)"];
  * UserApp->WiMOD  [label="convert(LowLevelData, txIndData)"];
  * UserApp<<WiMOD  ;
  * UserApp->UserApp [label="further processing"];
  * ...;
  * \endmsc
  *
  * @code
  * void myTxInd(TWiMODLR_HCIMessage& rxMsg) {
  *  TWiMODLORAWAN_TxIndData txData;
  *
  *  // convert/copy the raw message to tx indication data
  *  if (wimod.convert(rxMsg, &txData)) {
  *      // OK, process data
  *      ...
  *  }
  * }
  * ...
  * void setup() {
  *  ...
  *  // setup user callback(s) for TX indication events
  *  wimod.RegisterTxUDataIndicationClient(myTxInd);
  * }
  * ...
  * @endcode
  */
 void WiMODProLink::RegisterTxUDataIndicationClient(TTxUDataIndicationCallback cb)
 {
     SapLoRaWan.RegisterTxUDataIndicationClient(cb);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "RX U-Data Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="RegisterRxUDataIndicationClient(clientCB)"];
  * ...;
  * UserApp<<=WiMOD [label="RxUDataIndication()"];
  * \endmsc
  */
 void WiMODProLink::RegisterRxUDataIndicationClient(TRxUDataIndicationCallback cb)
 {
     SapLoRaWan.RegisterRxUDataIndicationClient(cb);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "RX C-Data Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="RegisterRxCDataIndicationClient(clientCB)"];
  * ...;
  * UserApp<<=WiMOD [label="RxCDataIndication()"];
  * \endmsc
  */
 void WiMODProLink::RegisterRxCDataIndicationClient(TRxCDataIndicationCallback cb)
 {
     SapLoRaWan.RegisterRxCDataIndicationClient(cb);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "RX MAC Cmd Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="RegisterRxMacCmdIndicationClient(clientCB)"];
  * ...;
  * UserApp<<=WiMOD [label="RxMacCmdIndication()"];
  * \endmsc
  */
 void WiMODProLink::RegisterRxMacCmdIndicationClient(TRxMacCmdIndicationCallback cb)
 {
     SapLoRaWan.RegisterRxMacCmdIndicationClient(cb);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "Joined Nwk Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="RegisterJoinedNwkIndicationClient(clientCB)"];
  * ...;
  * UserApp<<=WiMOD [label="JoinedNwkIndication()"];
  * \endmsc
  */
 void WiMODProLink::RegisterJoinedNwkIndicationClient(TJoinedNwkIndicationCallback cb)
 {
     SapLoRaWan.RegisterJoinedNwkIndicationClient(cb);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "RX ACK (data) Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="RegisterRxAckIndicationClient(clientCB)"];
  * ...;
  * UserApp<<=WiMOD [label="RxAckIndication()"];
  * \endmsc
  */
 void WiMODProLink::RegisterRxAckIndicationClient(TRxAckIndicationCallback cb)
 {
     SapLoRaWan.RegisterRxAckIndicationClient(cb);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Tries to send transmit U-Data to network server via RF link
  *
  *
  * @param data       pointer to data structure containing the TX-data and options.
  *                   @see TWiMODLORAWAN_TX_Data for details
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * \msc
  * UserApp,WiMOD,Server;
  * ... ;
  * UserApp=>WiMOD  [label="SendUData(data)"];
  * WiMOD->Server   [label="transfer data"];
  * UserApp<<WiMOD  [label="true/false"];
  * ...;
  * \endmsc
  *
  * @code
  * ...
  * // local variable
  * TWiMODProLinkLORAWAN_TX_Data txData;
  *
  * // setup tx packet
  * txData.Port   = 1;
  * txData.Length =  strlen("Hello World!");
  * strncpy(txData.Payload, "Hello World!", WiMODLORAWAN_APP_PAYLOAD_LEN);
  *
  * // send data
  * if (!wimod.SendUData(&txData)= {
  *   // error transmitting data
  *   // DutyCycle problem? check channel block time
  *   if (data.ChannelBlockTime >0) {
  *      // wait until blocking time is over
  *   }
  * }
  * ...
  * @endcode
  */
 bool WiMODProLink::SendUData(TWiMODProLinkLORAWAN_TX_Data* data,
                              TWiMODLRResultCodes*         hciResult,
                              UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.SendUData(data, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Tries to send transmit C-Data to network server via RF link
  *
  *
  * @param data       pointer to data structure containing the TX-data and options.
  *                   @see TWiMODLORAWAN_TX_Data for details
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * \msc
  * UserApp,WiMOD,Server;
  * ... ;
  * UserApp=>WiMOD  [label="SendCData(data)"];
  * WiMOD->Server   [label="transfer data"];
  * UserApp<<WiMOD  [label="true/false"];
  * ...;
  * WiMOD << Server [label= "ACK"];
  * --- [label="if ack callback is registered"];
  * UserApp << WiMOD [label="myAckCallback"];
  * ...;
  *
  * \endmsc
  *
  * @code
  * ...
  * // local variable
  * TWiMODProLinkLORAWAN_TX_Data txData;
  *
  * // setup tx packet
  * txData.Port   = 1;
  * txData.Length =  strlen("Hello World!");
  * strncpy(txData.Payload, "Hello World!", WiMODLORAWAN_APP_PAYLOAD_LEN);
  *
  * // send data
  * wimod.SendCData(&txData);
  * ...
  * // if ACK callback has been registered: wait for callback
  * // to be called and check the received indication data
  * // in order to get the status of the transmission
  * ...
  * @endcode
  */
 bool WiMODProLink::SendCData(TWiMODProLinkLORAWAN_TX_Data* data,
                              TWiMODLRResultCodes*         hciResult,
                              UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.SendCData(data, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Sets a new radio config parameter set of the WiMOD
  *
  *
  * @param data       pointer to data structure containing the new parameters
  *                   @see TWiMODLORAWAN_TX_Data for details
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * ...
  * // local variable
  * TWiMODLORAWAN_RadioStackConfig radioCfg;
  *
  * // setup new config
  * radioCfg.DataRateIndex   = (uint8_t) LoRaWAN_DataRate_EU868_LoRa_SF9_125kHz;
  * radioCfg.TXPowerLevel    = LORAWAN_TX_POWER_LEVEL_MIN;
  * radioCfg.Options         = LORAWAN_STK_OPTION_ADR |
  *                            LORAWAN_STK_OPTION_DEV_CLASS_C |
  *                            LORAWAN_STK_OPTION_EXT_PKT_FORMAT;
  * radioCfg.PowerSavingMode = LORAWAN_POWER_SAVING_MODE_OFF;
  * radioCfg.Retransmissions = 7;
  * radioCfg.BandIndex       = LORAWAN_BAND_EU_868_RX2_SF9;
  *
  * // set new radio config
  * wimod.SetRadioStackConfig(&radioCfg);
  *
  * // wait a little bit for config activation
  * @endcode
  *
  */
 bool WiMODProLink::SetRadioStackConfig(TWiMODProLinkLORAWAN_RadioStackConfig* data,
                                        TWiMODLRResultCodes*         hciResult,
                                        UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.SetRadioStackConfig(data, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);

 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Gets the current radio config parameter set of the WiMOD
  *
  *
  * @param data       pointer to data structure for storing the requested information
  *                   @see TWiMODLORAWAN_TX_Data for details
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * ...
  * // local variable
  * TWiMODLORAWAN_RadioStackConfig radioCfg;
  *
  * // get current radio config
  * if (wimod.GetRadioStackConfig(&radioCfg)) {
  *  // check / process
  *  ...
  * }
  * @endcode
  *
  */
 bool WiMODProLink::GetRadioStackConfig(TWiMODProLinkLORAWAN_RadioStackConfig* data,
                                        TWiMODLRResultCodes*         hciResult,
                                        UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.GetRadioStackConfig(data, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Deactivate the device (logical disconnect from lora network)
  *
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * ...
  * // "disconnect" this endnode from the network
  * if (wimod.DeactivateDevice()) {
  *      // node is disconnected and can not transfer data to server
  *      // unless it will be re-activated
  * }
  * ...
  * @endcode
  */
 bool WiMODProLink::DeactivateDevice(TWiMODLRResultCodes*         hciResult,
                                     UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.DeactivateDevice(&localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Reset all internal settings to default values (incl. DevEUI !!!)
  *
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * ...
  * // do a complete factory reset of the WiMOD module
  * if (wimod.FactoryReset()) {
  *      // WiMOD module will reset all internal values and will
  *      // do a reboot;
  *
  *      // wait a while for reboot to be completed
  * }
  * ...
  * @endcode
  */
 bool WiMODProLink::FactoryReset(TWiMODLRResultCodes*         hciResult,
                                 UINT8*                      rspStatus)
 {

     localHciRes = SapLoRaWan.FactoryReset(&localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);

 }


 //-----------------------------------------------------------------------------
 /**
  * @brief Sets a new DeviceEUI (aka. IEEE-Address) to the WiMOD
  *
  * Note: Setting a new DeviceEUI is requires to switch to customer operation
  *       mode. In "normal" application mode, this command is locked.
  *
  * @param deviceEUI  pointer to data structure containing the new parameters
  *                   (Must be an pointer of a 64bit address)
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * ...
  * // (local) variable for the device EUI
  * uint8_t devEUI[8];
  *
  * // setup deviceEUI
  * ...
  *
  * // send the devEUI to the WiMOD module
  * if (wimod.SetDeviceEUI(devEUI)) {
  *      // WiMOD module will use the given devEUI...
  * }
  * ...
  * @endcode
  */
 bool WiMODProLink::SetDeviceEUI(const UINT8*                deviceEUI,
                                 TWiMODLRResultCodes*         hciResult,
                                 UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.SetDeviceEUI(deviceEUI, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);

 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Gets the  DeviceEUI (aka. IEEE-Address) of the WiMOD
  *
  *
  * @param deviceEUI  pointer for storing the received 64bit address
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * ...
  * // (local) variable for the device EUI
  * uint8_t devEUI[8];
  *
  * // get the devEUI
  * if (wimod.GetDeviceEUI(devEUI)) {
  *      ...
  * }
  * ...
  * @endcode
  */
 bool WiMODProLink::GetDeviceEUI(UINT8*                      deviceEUI,
                                 TWiMODLRResultCodes*         hciResult,
                                 UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.GetDeviceEUI(deviceEUI, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);

 }


 //-----------------------------------------------------------------------------
 /**
  * @brief Gets the  current status of the network "connection"
  *
  *
  * @param nwkStatus  pointer for storing the requested information
  *                   @see LORAWAN_NWK_STATUS defines; e.g.:
  *                     - LORAWAN_NWK_STATUS_INACTIVE,
  *                     - LORAWAN_NWK_STATUS_ACTIVE_ABP,
  *                     - LORAWAN_NWK_STATUS_ACTIVE_OTAA,
  *                     - LORAWAN_NWK_STATUS_JOINING_OTAA
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * ...
  * // (local) variable
  * TWiMODLORAWAN_NwkStatus_Data nwkStatus;
  *
  * // get the nwk status
  * if (wimod.GetNwkStatus(&nwkStatus)) {
  *      switch (nwkStatus.NetworkStatus):
  *      case LORAWAN_NWK_STATUS_INACTIVE:    // device is not "connected"
  *      case LORAWAN_NWK_STATUS_ACTIVE_ABP:  // device has been activated by ABP
  *      case LORAWAN_NWK_STATUS_ACTIVE_OTAA: // device has been activated by OTAA
  *      case LORAWAN_NWK_STATUS_JOINING_OTAA:// an OTAA activation procedure is currently pending
  *      ...
  * }
  * ...
  * @endcode
  */
 bool WiMODProLink::GetNwkStatus(TWiMODLORAWAN_NwkStatus_Data*   nwkStatus,
                                 TWiMODLRResultCodes*            hciResult,
                                 UINT8*                          rspStatus)
 {
     localHciRes = SapLoRaWan.GetNwkStatus(nwkStatus, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Send a MAC command to the server; expert level only
  *
  * @param cmd      pointer containing the MAC command and parameters
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * ...
  * // (local) variable
  * TWiMODLORAWAN_MacCmd macCmd;
  *
  * // setup
  * macCmd.DataServiceType = LORAWAN_MAC_DATA_SERVICE_TYPE_U_DATA;
  * macCmd.MacCmdID = // see LoRa spec. for MAC command IDs
  * macCmd.Length = ...;
  * macCmd.Payload = ...;
  *
  * // send mac command
  * if (wimod.SendMacCmd(macCmd)) {
  *      ...
  * }
  * ...
  * @endcode
  */
 bool WiMODProLink::SendMacCmd(const TWiMODLORAWAN_MacCmd* cmd,
                               TWiMODLRResultCodes*         hciResult,
                               UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.SendMacCmd(cmd, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }



 //-----------------------------------------------------------------------------
 /**
  * @brief Setup a custom config for tx power settings; expert level only
  *
  * @param rfGain     new rfGain value for tx power settings; see HCI Spec.
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  */
 bool WiMODProLink::SetCustomConfig(const INT8                  rfGain,
                                    TWiMODLRResultCodes*         hciResult,
                                    UINT8*                      rspStatus)
 {
     localHciRes = SapLoRaWan.SetCustomConfig(rfGain, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Get the current offet for tx power level; expert level only
  *
  * @param rfGain     pointer to store the offset value for tx power settings
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  */
 bool WiMODProLink::GetCustomConfig(INT8*                rfGain,
                                    TWiMODLRResultCodes*  hciResult,
                                    UINT8*               rspStatus)
 {
     localHciRes = SapLoRaWan.GetCustomConfig(rfGain, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }


 //-----------------------------------------------------------------------------
 /**
  * @brief Get the supported bands of this firmware
  *
  * @param supportedBands  pointer  to store area for result
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  */

 bool WiMODProLink::GetSupportedBands(TWiMODLORAWAN_SupportedBands* supportedBands,
                                    TWiMODLRResultCodes*  hciResult,
                                    UINT8*               rspStatus)
 {
     localHciRes = SapLoRaWan.GetSupportedBands(supportedBands, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Get the configured TX limits for all sub-bands
  *
  * @param txPwrLimitCfg  pointer  to store area for result
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  */
 bool WiMODProLink::GetTxPowerLimitConfig(TWiMODLORAWAN_TxPwrLimitConfig* txPwrLimitCfg,
                                    TWiMODLRResultCodes*  hciResult,
                                    UINT8*               rspStatus)
 {
     localHciRes = SapLoRaWan.GetTxPowerLimitConfig(txPwrLimitCfg, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Set a single TX limit for a single sub-band
  *
  * @param txPwrLimitCfg  reference to read the data from
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  */
 bool WiMODProLink::SetTxPowerLimitConfig(TWiMODLORAWAN_TxPwrLimitConfig& txPwrLimitCfg,
                                    TWiMODLRResultCodes*  hciResult,
                                    UINT8*               rspStatus)
 {
     localHciRes = SapLoRaWan.SetTxPowerLimitConfig(txPwrLimitCfg, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }




 //-----------------------------------------------------------------------------
 /**
  * @brief Set the Battery Level Status
  *
  * @param battStatus Status value; 0 : mains power, 1-254 : batt level; 255: undefiend
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  */
 bool WiMODProLink::SetBatteryLevelStatus(UINT8 battStatus,
                                     TWiMODLRResultCodes*  hciResult,
                                     UINT8*                rspStatus)
 {
     localHciRes = SapLoRaWan.SetBatteryLevelStatus(battStatus,  &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Set the Device Nonce / DevNonce for the next Join OTAA procedure
  *
  * @param devNonce  16 bit value ( Number used only once)
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  */
 bool WiMODProLink::SetDeviceNonce(const UINT16 devNonce,
                                   TWiMODLRResultCodes*  hciResult,
                                   UINT8*                rspStatus)
 {
     localHciRes = SapLoRaWan.SetDeviceNonce(devNonce, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

//-----------------------------------------------------------------------------
/**
* @brief Get the Device Nonce / DevNonce that will be used for next Join OTAA procedure
*
* @param devNonce  pointer to 16 bit value where to store the requested value
*
* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*/
 bool WiMODProLink::GetDeviceNonce(UINT16* devNonce,
                                    TWiMODLRResultCodes*  hciResult,
                                    UINT8*               rspStatus)
 {
     localHciRes = SapLoRaWan.GetDeviceNonce(devNonce, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

//-----------------------------------------------------------------------------
 /**
 * @brief Set a (new) Configuration for Multicast Mode
 *
 * @param mcastCfg  pointer to a multicast configuration structure
 *
 * @param hciResult Result of the local command transmission to module
 *                  This is an optional parameter.
 *
 * @param rspStatus Status byte contained in the local response of the module
 *                  This is an optional parameter.
 *
 * @retval true     if everything is ok
 * @retval false    if something went wrong; see hciResult & rspStatus for details
 */
bool WiMODProLink::SetMulticastConfig(TWiMODLORAWAN_McastConfig& mcastCfg,
                                      TWiMODLRResultCodes*  hciResult,
                                      UINT8*                rspStatus)
{
    localHciRes = SapLoRaWan.SetMulticastConfig(mcastCfg, &localStatusRsp);
    return copyLoRaWanResultInfos(hciResult, rspStatus);
}

//-----------------------------------------------------------------------------
 /**
 * @brief Get a single Multicase configuration from module
 *
 * @param mcastCfg  pointer to a multicast configuration structure
 *                  The MultiCase index has be be setup prior calling this function.
 *                  The resulting information will be put into this pointer
 *
 * @param hciResult Result of the local command transmission to module
 *                  This is an optional parameter.
 *
 * @param rspStatus Status byte contained in the local response of the module
 *                  This is an optional parameter.
 *
 * @retval true     if everything is ok
 * @retval false    if something went wrong; see hciResult & rspStatus for details
 */
bool WiMODProLink::GetMulticastConfig(TWiMODLORAWAN_McastConfig* mcastCfg,
                                      TWiMODLRResultCodes*  hciResult,
                                      UINT8*                rspStatus)
{
    localHciRes = SapLoRaWan.GetMulticastConfig(mcastCfg, &localStatusRsp);
    return copyLoRaWanResultInfos(hciResult, rspStatus);
}

//-----------------------------------------------------------------------------
 /**
 * @brief Remove a single Multicast configuration from module
 *
 * @param mcastIndex the index of the configuration block to be removed.
 *
 * @param hciResult Result of the local command transmission to module
 *                  This is an optional parameter.
 *
 * @param rspStatus Status byte contained in the local response of the module
 *                  This is an optional parameter.
 *
 * @retval true     if everything is ok
 * @retval false    if something went wrong; see hciResult & rspStatus for details
 */

bool WiMODProLink::RemoveMulticastConfig(const UINT8            mcastIndex,
                                        TWiMODLRResultCodes*    hciResult,
                                        UINT8*                  rspStatus)
{
    localHciRes = SapLoRaWan.RemoveMulticastConfig(mcastIndex, &localStatusRsp);
    return copyLoRaWanResultInfos(hciResult, rspStatus);
}

 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "Reset DevNonce Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="RegisterResetDevNonceIndicationClient(clientCB)"];
  * ...;
  * UserApp<<=WiMOD [label="ResetDevNonceIndication()"];
  * \endmsc
  */
 void WiMODProLink::RegisterResetDevNonceIndicationClient(TResetDevNonceIndicationCallback cb)
 {
     SapLoRaWan.RegisterResetDevNonceIndicationClient(cb);
 }


 //-----------------------------------------------------------------------------
 /**
  * @brief Set the Join Nonce for the next Join OTAA procedure
  *
  * @param joinNonce  16 bit value ( Number used only once)
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  */
 bool WiMODProLink::SetJoinNonce(const UINT16 joinNonce,
                                   TWiMODLRResultCodes*  hciResult,
                                   UINT8*                rspStatus)
 {
     localHciRes = SapLoRaWan.SetJoinNonce(joinNonce, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Get the Join Nonce that will be used for next Join OTAA procedure
  *
  * @param joinNonce  pointer to 16 bit value where to store the requested value
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  */
 bool WiMODProLink::GetJoinNonce(UINT16* joinNonce,
                                 TWiMODLRResultCodes*  hciResult,
                                 UINT8*               rspStatus)
 {
     localHciRes = SapLoRaWan.GetJoinNonce(joinNonce, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }


//-----------------------------------------------------------------------------
/**
* @brief Register a callback function for the event "Link Disconnect Indication"
*
* This registered callback is called when the specified event is called by
* the WiMOD stack.
*
* @param   cb          pointer to a callback function that should be called
*                      if the event occurs.
* \msc
* UserApp,WiMOD;
* UserApp=>WiMOD  [label="RegisterLinkDiconnectIndicationClient(clientCB)"];
* ...;
* UserApp<<=WiMOD [label="LinkDisconnectedIndication()"];
* \endmsc
*/
void WiMODProLink::RegisterLinkDiconnectIndicationClient(TLinkDisconnectIndicationCallback cb)
 {
     SapLoRaWan.RegisterLinkDisconnectIndicationClient(cb);
 }


 //-----------------------------------------------------------------------------
/**
* @brief Send a Network Time Request /DevTimeRequest via MAC Cmd to LNS
*
* @param devTimeInfo pointer to store initial response data
*
* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*/
bool WiMODProLink::SendNwkTimeRequest(TWiMODLORAWAN_DevTimeReqInfo* devTimeInfo,
                             TWiMODLRResultCodes*  hciResult,
                             UINT8*               rspStatus)
{
 localHciRes = SapLoRaWan.SendNwkTimeRequest(devTimeInfo, &localStatusRsp);
 return copyLoRaWanResultInfos(hciResult, rspStatus);
}


 //-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "DeviceTimeAnser Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="RegisterNwkTimeAnsIndicationClient(clientCB)"];
  * ...;
  * UserApp<<=WiMOD [label="DeviceTimeAnswerIndication()"];
  * \endmsc
  */
 void WiMODProLink::RegisterNwkTimeAnsIndicationClient(TNwkDeviceTimeAnsIndicationCallback cb)
 {
     SapLoRaWan.RegisterDeviceTimeAnsIndicationClient(cb);
 }


//-----------------------------------------------------------------------------
/**
* @brief Convert a received low level HCI-Msg to a high-level NkwDeviceTimeAnswer structure
*
* This function should be used by the NwkTimeAnswer Indication Callback function
* prior processing the received data message.
*
* @param   RxMsg       Reference to low-level HCI message.
*                      @warning DO NOT MANIPULATE THESE VALUES !!!
*
* @param   info      Pointer to the buffer where to store the received information
*
* @retval true     if the conversion was successful
*
*
* \msc
* UserApp,WiMOD,Server;
* |||;
* UserApp->WiMOD  [label="RegisterNwkTimeAnsIndicationClient(myNwkTimeAnsInd)"];
* ...;
* UserApp->WiMOD  [label="SendNwkTimeRequest(data)"];
* WiMOD->Server   [label="MAC Command execution"];
* |||;
* ...;
* |||;
* UserApp<<=WiMOD [label="myNwkTimeAnsInd(LowLevelData)"];
* UserApp->WiMOD  [label="convert(LowLevelData, info)"];
* ...;
* UserApp<<WiMOD  ;
* UserApp->UserApp [label="further processing"];
* \endmsc
*
*/
 bool WiMODProLink::convert(TWiMODLR_HCIMessage& RxMsg,
         TWiMODLORAWAN_DevTimeAnsInfo* info)
 {
     return SapLoRaWan.convert(RxMsg, info);
 }


//-----------------------------------------------------------------------------
/**
* @brief Convert a received low level HCI-Msg to a high-level Multicast Data structure
*
* This function should be used by the MultiCast RX Data Indication Callback function
* prior processing the received data message.
*
* @param   RxMsg       Reference to low-level HCI message.
*                      @warning DO NOT MANIPULATE THESE VALUES !!!
*
* @param   info      Pointer to the buffer where to store the received information
*
* @retval true     if the conversion was successful
*
*
* \msc
* UserApp,WiMOD,Server;
* |||;
* UserApp->WiMOD  [label="RegisterMulticastDataIndicationClient(myMCastDataInd)"];
* ...;
* |||;
* UserApp<<=WiMOD [label="myMCastDataInd(LowLevelData)"];
* UserApp->WiMOD  [label="convert(LowLevelData, info)"];
* ...;
* UserApp<<WiMOD  ;
* UserApp->UserApp [label="further processing"];
* \endmsc
*
*/
 bool WiMODProLink::convert(TWiMODLR_HCIMessage& RxMsg,
                            TWiMODLORAWAN_McastData* mcastData)
 {
     return SapLoRaWan.convert(RxMsg, mcastData);
 }

//-----------------------------------------------------------------------------
/**
* @brief Convert a received low level HCI-Msg to a high-level Multicast Data structure
*
* This function should be used by the MultiCast RX Data Indication Callback function
* prior processing the received data message.
*
* @param   RxMsg       Reference to low-level HCI message.
*                      @warning DO NOT MANIPULATE THESE VALUES !!!
*
* @param   info      Pointer to the buffer where to store the received information
*
* @retval true     if the conversion was successful
*
*
* \msc
* UserApp,WiMOD,Server;
* |||;
* UserApp->WiMOD  [label="RegisterMulticastInvalidDataIndicationClient(myInvalidMCastDataInd)"];
* ...;
* |||;
* UserApp<<=WiMOD [label="myInvalidMCastDataInd(LowLevelData)"];
* UserApp->WiMOD  [label="convert(LowLevelData, info)"];
* ...;
* UserApp<<WiMOD  ;
* UserApp->UserApp [label="further processing"];
* \endmsc
*
*/
 bool WiMODProLink::convert(TWiMODLR_HCIMessage& RxMsg,
                            TWiMODLORAWAN_McastNoData*  mcastErrData)
 {
     return SapLoRaWan.convert(RxMsg, mcastErrData);
 }


//-----------------------------------------------------------------------------
/**
* @brief Register a callback function for the event "MultiCast Data (Rx) Indication"
*
* This registered callback is called when the specified event is called by
* the WiMOD stack.
*
* @param   cb          pointer to a callback function that should be called
*                      if the event occurs.
* \msc
* UserApp,WiMOD;
* UserApp=>WiMOD  [label="RegisterMulticastDataIndicationClient(clientCB)"];
* ...;
* UserApp<<=WiMOD [label="MCastDataIndication()"];
* \endmsc
*/
void WiMODProLink::RegisterMulticastDataIndicationClient(TMCastDataIndicationCallback cb)
{
 SapLoRaWan.RegisterMulticastDataIndicationClient(cb);
}

//-----------------------------------------------------------------------------
/**
* @brief Register a callback function for the event "Invalid MultiCast Data (RX) Indication"
*
* This registered callback is called when the specified event is called by
* the WiMOD stack.
*
* @param   cb          pointer to a callback function that should be called
*                      if the event occurs.
* \msc
* UserApp,WiMOD;
* UserApp=>WiMOD  [label="RegisterMulticastInvalidDataIndicationClient(clientCB)"];
* ...;
* UserApp<<=WiMOD [label="InvalidMCastDataIndication()"];
* \endmsc
*/
void WiMODProLink::RegisterMulticastInvalidDataIndicationClient(TMCastInvalidDataIndicationCallback cb)
{
     SapLoRaWan.RegisterMulticastInvalidDataIndicationClient(cb);
}


//===============================================================================
//
// ProLink Proprietary LR-BASE RadioLink (end device to end device communication)
//
//===============================================================================

#if 1

//-----------------------------------------------------------------------------
/**
* @brief Get the current RadioConfig used for the proprietary LoRa communication feature
*
* This function tries to get the current configuration parameters that are used
* in the proprietary LoRa communication feature (LR-BASE) of the ProLink firmware.
*
* @param   radioCfg    pointer to a structure where to store the retrieved
*                      information of the radio module.
*
* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*/
bool WiMODProLink::GetRadioLinkRadioConfig(TWiMODLR_ProLinkRadioLink_RadioConfig* radioCfg,
                                           TWiMODLRResultCodes*  hciResult,
                                           UINT8*               rspStatus)
{
  localHciRes = SapRadioLink.GetRadioConfig(radioCfg, &localStatusRsp);
  return copyProLinkRadioLinkResultInfos(hciResult, rspStatus);
}

//-----------------------------------------------------------------------------
/**
* @brief Set a new RadioConfig to be used for the proprietary LoRa communication feature
*
* This function tries to set a new configuration parameter set that should be used
* in the proprietary LoRa communication feature (LR-BASE) of the ProLink firmware.
*
* @param   radioCfg    pointer to a structure where to store the retrieved
*                      information of the radio module.
*
* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*/
bool WiMODProLink::SetRadioLinkRadioConfig(const TWiMODLR_ProLinkRadioLink_RadioConfig* radioCfg,
                                         TWiMODLRResultCodes*         hciResult,
                                         UINT8*                      rspStatus)
{
  localHciRes = SapRadioLink.SetRadioConfig(radioCfg, &localStatusRsp);
  return copyProLinkRadioLinkResultInfos(hciResult, rspStatus);
}

//-----------------------------------------------------------------------------
/**
* @brief Reset the RadioConfig for the proprietary LoRa communication feature to defaults
*
* This function tries to reset the configuration parameter set used
* in the proprietary LoRa communication feature (LR-BASE) of the ProLink firmware
* to the build-in factory defaults.
*
* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*/
bool WiMODProLink::ResetRadioLinkRadioConfig(TWiMODLRResultCodes*     hciResult,
                                             UINT8*                   rspStatus)
{
  localHciRes = SapRadioLink.ResetRadioConfig(&localStatusRsp);
  return copyProLinkRadioLinkResultInfos(hciResult, rspStatus);
}

//-----------------------------------------------------------------------------
/**
* @brief Sets an AES encryption key for the proprietary LoRa communication feature.
*
* This function tries to set an AES encryption key that can be used
* in the proprietary LoRa communication feature (LR-BASE) of the ProLink firmware.
*
* Hint: In order to activate / use encrypted communication this feature has to be
*       activated in the MiscOptions-field of the RadioConfig settings.
*
* @param key       a pointer to the AES key to use (128bit)

* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*
* @code
* // generate a secure AES key
* uint8_t aesKey[16] = {0x00, 0x01, 0x02, ... 0x10};
*
* // setup AES Key
* wimod.SetAesKey_ProLink(key);
*
* //enable encrypted communication for proprietary mode
* TWiMODLR_ProLinkRadioLink_RadioConfig* radioCfg;
*
* wimod.GetRadioLinkRadioConfig(&radioCfg);
* radioConfig.MiscOptions |= PROLINK_RADIOLINK_RADIO_CFG_MISC_HCI_ENCTRYPTION_ENABLED;
* wimod.SetRadioLinkRadioConfig(&radioCfg);
* ...
* // send an encrypted message
* TWiMODLR_RadioLink_Msg radioMsg;
*
* radioMsg.DestinationGroupAddress  = 0x10;
* radioMsg.DestinationDeviceAddress = 0x1234;
* radioMsg.Length =  strlen("Hello World!");
* strncpy(radioMsg.Payload, "Hello World!", WiMODLORAWAN_APP_PAYLOAD_LEN);
*
* wimod.SendRadioLinkUData(&radioMsg);
* @endcode
*
*/
bool WiMODProLink::SetRadioLinkAesKey(const UINT8* key,
                                     TWiMODLRResultCodes*         hciResult,
                                     UINT8*                      rspStatus)
{
  localHciRes = SapRadioLink.SetAesKey(key, &localStatusRsp);
  return copyProLinkRadioLinkResultInfos(hciResult, rspStatus);
}


//-----------------------------------------------------------------------------
/**
* @brief Gets the current AES encryption of the proprietary LoRa communication feature.
*
* This function tries to get the current AES encryption key that can be used
* in the proprietary LoRa communication feature (LR-BASE) of the ProLink firmware.
*
* Hint: If the encryption key is actually used it defined by the
*       MiscOptions-field in the RadioConfig settings structure.

* @param key       a pointer where to store the retrieved key (128bit)
*
* @param hciResult Result of the local command transmission to module
*                  This is an optional parameter.
*
* @param rspStatus Status byte contained in the local response of the module
*                  This is an optional parameter.
*
* @retval true     if everything is ok
* @retval false    if something went wrong; see hciResult & rspStatus for details
*/
bool WiMODProLink::GetRadioLinkAesKey( UINT8* key,
                                     TWiMODLRResultCodes*         hciResult,
                                     UINT8*                      rspStatus)
{
  localHciRes = SapRadioLink.GetAesKey(key, &localStatusRsp);
  return copyProLinkRadioLinkResultInfos(hciResult, rspStatus);
}

//-----------------------------------------------------------------------------
/**
 * @brief Tries to send transmit U-Data to a peer using proprietary LoRa mode
 *
 *
 * @see TWiMODLRResultCodes for interpretation of the values
 *
 * @param data      Data structure containing the TX-data and options.
 *                   @see TWiMODLR_RadioLink_Msg for details
 *
 * @param hciResult Result of the local command transmission to module
 *                  This is an optional parameter.
 *
 * @param rspStatus Status byte contained in the local response of the module
 *                  This is an optional parameter.
 *
 * @retval true     if everything is ok
 * @retval false    if something went wrong; see hciResult & rspStatus for details
 *
 * \msc
 * UserApp,WiMOD,RemotePeer;
 * ... ;
 * UserApp=>WiMOD       [label="SendUData(data)"];
 * WiMOD->RemotePeer    [label="transfer data"];
 * UserApp<<WiMOD       [label="true/false"];
 * ...;
 * \endmsc
 *
 * @code
 * ...
 * // local variable
 * TWiMODLR_RadioLink_Msg txData;
 *
 * // setup tx packet
 * txData.DestinationGroupAddress   = 0x10;
 * txData.DestinationDeviceAddress  = 0x1234;
 * txData.Length =  strlen("Hello World!");
 * strncpy(txData.Payload, "Hello World!", WiMODLORAWAN_APP_PAYLOAD_LEN);
 *
 * // send data
 * wimod.SendRadioLinkUData(&txData);
 * ...
 * @endcode
 */
bool WiMODProLink::SendRadioLinkUData(const TWiMODLR_RadioLink_Msg* data,
                              TWiMODLRResultCodes*         hciResult,
                              UINT8*                      rspStatus)
 {
     localHciRes = SapRadioLink.SendUData(data, &localStatusRsp);
     return copyProLinkRadioLinkResultInfos(hciResult, rspStatus);
 }


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

/**
 * @brief Convert a frequency in Hz to the corresponding low level register values
 *
 *
 * @param freq      Target frequencey in Hz
 *
 * @param msb       Pointer to register value for MSB-Part
 * @param mid       Pointer to register value for MID-Part
 * @param lsb       Pointer to register value for LSB-Part
 */
void WiMODProLink::calcFreqToRegister(uint32_t freq, uint8_t* msb, uint8_t* mid, uint8_t* lsb)
{
    if (msb && mid && lsb) {
        FreqCalc_calcFreqToRegister(freq, msb, mid, lsb);
    }
}

/**
 * @brief Convert a frequency registers to frequency in Hz
 *
 * @param msb       register value for MSB-Part
 * @param mid       register value for MID-Part
 * @param lsb       register value for LSB-Part
 *
 * return Frequency in Hz
 */
uint32_t WiMODProLink::calcRegisterToFreq(uint8_t msb, uint8_t mid, uint8_t lsb)
{
    return FreqCalc_calcRegisterToFreq(msb, mid, lsb);
}

//-----------------------------------------------------------------------------
 /**
  * @brief Register a callback function for the event "RX U-Data Indication"
  *
  * This registered callback is called when the specified event is called by
  * the WiMOD stack running in proprietary LR-BASE mode.
  *
  * @param   cb          pointer to a callback function that should be called
  *                      if the event occurs.
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD  [label="RegisterRadioLinkRxUDataIndicationClient(clientCB)"];
  * ...;
  * UserApp<<=WiMOD [label="RxRadioLinkUDataIndication()"];
  * \endmsc
  */
void WiMODProLink::RegisterRadioLinkRxUDataIndicationClient(TRadioLinkUDataRxIndicationCallback cb)
{
 SapRadioLink.RegisterUDataRxClient(cb);
}


//-----------------------------------------------------------------------------
/**
 * @brief Register a callback function for the TX U-Data Indication - optional -
 *
 *
 * @see TWiMODLRResultCodes for interpretation of the values
 *
 * @param cb        Pointer a callback function
 *                  @see TRadioLinkUDataTxIndicationCallback for details
 *
 * \msc
 * UserApp,WiMOD,RemotePeer;
 * ... ;
 * UserApp -> WiMOD    [label="RegisterUDataTxClient(txUDataInd)"];
 * ...;
 * UserApp -> WiMOD    [label="SendRadioLinkUData(data)"];
 * WiMOD -> RemotePeer [label="transfer data"];
 * --- [label= "if callback is registered"];
 * UserApp << WiMOD    [label="txRadioLinkUDataInd()"];
 * ...;
 * \endmsc
 *
 * @code
 * // callback for U data Tx indication
 * void myUDataTxInd() {
 *     ...
 * }
 *
 * void setup() {
 *     ...
 *     // setup the callback
 *     wimod.RegisterRadioLinkTxUDataIndicationClient(myUDataTxInd);
 *     ...
 * }
 *
 * ...
 * @endcode
 */
void WiMODProLink::RegisterRadioLinkTxUDataIndicationClient(TRadioLinkUDataTxIndicationCallback cb)
{
    SapRadioLink.RegisterUDataTxClient(cb);
}





#endif
//===============================================================================
//
// Generic
//
//===============================================================================

 /**
  * @brief Generic Execution Function for HCI commands that are currently not implemented
  *
  * This funtion enables the user to execute various HCI commands that are
  * currently not implemented as commands within this API class.
  *
  * The user has to know the HCI Command IDs and has to decode the response data
  * on his own.
  *
  * @param info      pointer to a structure containing the HCI commands to execute
  *
  * @param hciResult Result of the local command transmission to module
  *                  This is an optional parameter.
  *
  * @param rspStatus Status byte contained in the local response of the module
  *                  This is an optional parameter.
  *
  * @retval true     if everything is ok
  * @retval false    if something went wrong; see hciResult & rspStatus for details
  *
  * @code
  * ...
  * // prepare command to send to WiMOD
  * TWiMODLR_Generic_CmdInfo cmdInfo;
  * cmdInfo.SapID    = 0x01; // DevMgmt
  * cmdInfo.MsgReqID = 0x01; // Ping Req
  * cmdInfo.MsgRspID = 0x02; // expected response
  *
  * // prepare payload for tx command
  * cmdInfo.CmdPayloadLength = 0
  * cmdInfo.CmdPayload[0] = 0xab;
  * ...
  *
  * // execute command
  * if (wimod.ExecuteGenericCmd(&cmdInfo)) {
  *      // extract cmd reponse data
  *      if (cmdInfo.CmdPayloadLength > 0) {
  *          // repsonse data available
  *          rspData =cmdInfo.CmdPayload[0]
  *          ...
  *          // process data
  *          ...
  *      }
  * }
  *
  * @endcode
  */
 bool WiMODProLink::ExecuteGenericCmd(TWiMODLR_Generic_CmdInfo*   info,
                                          TWiMODLRResultCodes*         hciResult,
                                   UINT8*                      rspStatus)
 {
     localHciRes = SapGeneric.ExecuteGenericCmd(info, &localStatusRsp);
     return copyLoRaWanResultInfos(hciResult, rspStatus);
 }



 //-----------------------------------------------------------------------------
 /**
  * @brief Gets the last HCI result code from the last executed command.
  *
  * If you missed setting the HciResult parameter while executing the last
  * command, this method can recall the last value of that parameter.
  *
  * @see TWiMODLRResultCodes for possible values.
  *
  * @return the result value of the last executed command
  *
  * \msc
  * UserApp,WiMOD;
  * UserApp=>WiMOD   [label="Ping()"];
  * UserApp<<WiMOD   [label="(false)"];
  * UserApp=>WiMOD   [label="GetGetLastHciResult()"];
  * UserApp<<WiMOD   [label="(result of last HCI TX operation)"];
  * ...;
  * \endmsc
  *
  * @code
  * ...
  * if (wimod.Ping() == false) {
  *  TWiMODLRResultCodes hciResult;
  *
  *  // get (local) result of HCI command transmission
  *  hciResult = wimod.GetLastHciResult();
  *
  *  // check result code
  *  switch (hciResult):
  *  case WiMODLR_RESULT_OK:                   // OK, no error
  *  case WiMODLR_RESULT_PAYLOAD_LENGTH_ERROR: // given payload is too big
  *  case WiMODLR_RESULT_PAYLOAD_PTR_ERROR:    // wrong pointer to payload (NULL?)
  *  case WiMODLR_RESULT_TRANMIT_ERROR,        // Error sending data to WiMOD via serial interface
  *  case WiMODLR_RESULT_SLIP_ENCODER_ERROR,   // Error during SLIP encoding
  *  case WiMODLR_RESULT_NO_RESPONSE           // The WiMOD did not respond to a request command
  *  ...
  * }
  *
  * ...
  * @endcode
  *
  */
 TWiMODLRResultCodes WiMODProLink::GetLastHciResult(void)
 {
     return lastHciRes;
 }

 //-----------------------------------------------------------------------------
 /**
  * @brief Gets the last response code of the WiMOD of the last executed command.
  *
  * If you missed setting the rspStatus parameter while executing the last
  * command, this method can recall the last value of that parameter.
  *
  * @see LORAWAN_STATUS_* defines for possible values.
  *
  * @return the result value of the last executed command
  *
  *  * @code
  * ...
  * if (wimod.Ping() == false) {
  *  uint8_t rsp;
  *
  *  // get (remote) response code
  *  rsp = wimod.GetLastResponseStatus();
  *
  *  // check result code
  *  switch (rsp):
  *  case LoRaWAN_Status_Ok:                   // OK; No error;
  *          // --> check "remote" ResponseStatus
  *  case LoRaWAN_Status_Error:                // general (un-specific) error
  *  case LoRaWAN_Status_Cmd_Not_Supported:    // Command is not supported (or unknown)
  *  case LoRaWAN_Status_Wrong_parameter:      // Wrong parameter applied
  *  case LoRaWAN_Status_Wrong_DeviceMode:     // Device is in wong device mode for specific command
  *  case LoRaWAN_Status_Device_Not_Activated: // Device has NOT been activated; command has not been executed
  *  case LoRaWAN_Status_Device_Busy:          // There is another operation pending; and or duty cycle restriction is active
  *  case LoRaWAN_Status_Queue_Full:           // internal command queue is full
  *  case LoRaWAN_Status_Length_Error:         // some error related to the given length information
  *  case LoRaWAN_Status_No_Factory_Settings:  // Factory settings are not available
  *  case LoRaWAN_Status_Channel_Blocked:      // Selected channel is blocked (duty cycle?)
  *  case LoRaWAN_Status_Channel_Not_Available: // Selected channel is not available
  *  ...
  * }
  *
  * ...
  * @endcode
  *
  */
 UINT8 WiMODProLink::GetLastResponseStatus(void)
 {
     return lastStatusRsp;
 }

 //------------------------------------------------------------------------------
 //
 // Section protected functions
 //
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------
 /**
  * @internal
  *
  * @brief dispatches an received indication message from the module
  *
  * @param rxMsg     reference to the received messasge
  *
  * @endinternal
  */
 void WiMODProLink::ProcessUnexpectedRxMessage(TWiMODLR_HCIMessage& rxMsg)
 {
     switch(rxMsg.SapID)
     {
         case    DEVMGMT_SAP_ID:
                 SapDevMgmt.DispatchDeviceMgmtMessage(rxMsg);
                 break;

         case    LORAWAN_SAP_ID:
                 SapLoRaWan.DispatchProLinkLoRaWANMessage(rxMsg);
                 break;

         case    PROLINK_RADIOLINK_SAP_ID:
                 SapRadioLink.DispatchRadioLinkProLinkMessage(rxMsg);
                 break;

         default:
                 if (StackErrorClientCB) {
                     StackErrorClientCB(WIMOD_STACK_ERR_UNKNOWN_RX_SAP_ID);
                 }
                 break;
     }
     return;
 }

 //------------------------------------------------------------------------------
 /**
  * @internal
  *
  * @brief copies information about last executed command into internal members
  *
  * @param hciResult   pointer to last hci Result code
  *
  * @param rspStatus   pointer to last hci response status code
  *
  * @retval true    if everything is ok
  *
  * @endinternal
  */
 bool WiMODProLink::copyDevMgmtResultInfos(TWiMODLRResultCodes* hciResult, UINT8* rspStatus)
 {

     cmdResult = false;

     if ((WiMODLR_RESULT_OK == localHciRes)
             && (localStatusRsp == DEVMGMT_STATUS_OK)) {
         cmdResult = true;
     }
     if (hciResult) {
         *hciResult = localHciRes;
     }
     if (rspStatus) {
         *rspStatus = localStatusRsp;
     }

     // backup last status data
     lastHciRes = localHciRes;
     lastStatusRsp = localStatusRsp;

     return cmdResult;
 }

 //------------------------------------------------------------------------------
 /**
  * @internal
  *
  * @brief copies information about last executed command into internal members
  *
  * @param hciResult   pointer to last hci Result code
  *
  * @param rspStatus   pointer to last hci response status code
  *
  * @retval true    if everything is ok
  *
  * @endinternal
  */
 bool WiMODProLink::copyLoRaWanResultInfos(TWiMODLRResultCodes* hciResult, UINT8* rspStatus)
 {

     cmdResult = false;

     if ((WiMODLR_RESULT_OK == localHciRes)
             && (localStatusRsp == LORAWAN_STATUS_OK)) {
         cmdResult = true;
     }
     if (hciResult) {
         *hciResult = localHciRes;
     }
     if (rspStatus) {
         *rspStatus = localStatusRsp;
     }

     // backup last status data
     lastHciRes = localHciRes;
     lastStatusRsp = localStatusRsp;

     return cmdResult;
 }

//------------------------------------------------------------------------------
/**
* @internal
*
* @brief copies information about last executed command into internal members
*
* @param hciResult   pointer to last hci Result code
*
* @param rspStatus   pointer to last hci response status code
*
* @retval true    if everything is ok
*
* @endinternal
*/
 bool WiMODProLink::copyProLinkRadioLinkResultInfos(TWiMODLRResultCodes* hciResult, UINT8* rspStatus)
  {

      cmdResult = false;

      if ((WiMODLR_RESULT_OK == localHciRes)
              && (localStatusRsp == PROLINK_RADIOLINK_STATUS_OK)) {
          cmdResult = true;
      }
      if (hciResult) {
          *hciResult = localHciRes;
      }
      if (rspStatus) {
          *rspStatus = localStatusRsp;
      }

      // backup last status data
      lastHciRes = localHciRes;
      lastStatusRsp = localStatusRsp;

      return cmdResult;
  }

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


//------------------------------------------------------------------------------
// EOF
//------------------------------------------------------------------------------



