/*****************************************************************************
 *
 * MODULE:             JN-AN-1200-ZigBee-RF4CE-Application-Template
 *
 * COMPONENT:          Receiver.c
 *
 * DESCRIPTION:        Receiver Implementation
 *
 * $HeadURL $
 *
 * $Revision: 12086 $
 *
 * $LastChangedBy: nxp46755 $
 *
 * $LastChangedDate: 2013-12-16 12:22:44 +0530 (Mon, 16 Dec 2013) $
 *
 * $Id: Receiver.c 12086 2013-12-16 06:52:44Z nxp46755 $
 *
 ****************************************************************************
 *
 * This software is owned by NXP B.V. and/or its supplier and is protected
 * under applicable copyright laws. All rights are reserved. We grant You,
 * and any third parties, a license to use this software solely and
 * exclusively on NXP products [NXP Microcontrollers such as JN516x, JN514x,
 * JN513x].
 * You, and any third parties must reproduce the copyright and warranty notice
 * and any other legend of ownership on each copy or partial copy of the
 * software.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 *
 * Copyright NXP B.V. 2014. All rights reserved
 *
 ***************************************************************************/

/****************************************************************************/
/***        Include files                                                 ***/
/****************************************************************************/
#include <jendefs.h>
#include <PeripheralRegs.h>
#include <string.h>
#include "RF4CE_API.h"
#include "Config.h"
#include "Printf.h"
#include "app_buttons.h"
#include "LcdDriver.h"

/****************************************************************************/
/***        Macro Definitions                                             ***/
/****************************************************************************/


/****************************************************************************/
/***        Type Definitions                                              ***/
/****************************************************************************/
typedef enum
{
    E_COLD_START,
    E_WAIT_FOR_EV_START_CFM,
    E_WARM_START,
    E_DISCOVERY,
    E_WAIT_FOR_EV_AUTODISC_CFM,
    E_PAIRING,
    E_WAIT_FOR_EV_PAIR_IND,
    E_WAIT_FOR_EV_PAIR_COMMSTATUS_IND,
    E_PAIRED,
    E_RUNNING,
    E_NLDE_IND,
    E_WAIT_FOR_EV_NLDE_CFM,
    E_DISC_IND,
    E_WAIT_FOR_EV_DISC_COMMSTATUS_IND,
    E_UNPAIR,
    E_WAIT_FOR_EV_UNPAIR_CFM,
} teState;


/****************************************************************************/
/***        Local Function Prototypes                                     ***/
/****************************************************************************/
PRIVATE void vInitSystem(void);
PRIVATE void vIdleLoop(void);
PRIVATE void vTimerISR(uint32 u32Device, uint32 u32ItemBitmap);
PRIVATE void vLongToString(char * str, uint32 u32Num);


/****************************************************************************/
/***        Exported Variables                                            ***/
/****************************************************************************/
extern uint8 gMAC_u8MaxBuffers;
extern uint8 u8WakeUpButton;

/****************************************************************************/
/***        Local Variables                                               ***/
/****************************************************************************/
PRIVATE volatile teState eState;
PRIVATE tuRF4CE_NibValue uNibValue;
PRIVATE bool_t gbAcceptPairTableUpdate = FALSE;
PRIVATE uint8 u8PairingRef;
PRIVATE uint8 u8NumOfPairTableEntries = 0;
PRIVATE uint8 u8CurrentIndex = 0;
PRIVATE uint32 gu32TimerCounter = 0;

PRIVATE tsRF4CE_AppCap  sRecAppCap = {USER_STRING_SPECIFIED,
                                      NUM_OF_SUPPORTED_DEVICE_TYPES,
                                      RESERVED,
                                      NUM_OF_SUPPORTED_PROFILES,
                                      RESERVED};
PRIVATE uint8 au8RecDevTypeList[NUM_OF_SUPPORTED_DEVICE_TYPES] = {RF4CE_DEVICE_TYPE_MEDIA_CENTER};
PRIVATE uint8 au8RecProfileIdList[NUM_OF_SUPPORTED_PROFILES] = {ZRC_PROFILE_ID};
PRIVATE uint32 u32AutoDiscDuration = AUTO_DISCOVERY_DURATION;
PRIVATE uint8 u8PairTableIndex[RF4CE_NWKC_MAX_PAIRING_TABLE_ENTRIES];
PRIVATE tuRF4CE_EventParam uParam;


/****************************************************************************/
/***        Exported Functions                                            ***/
/****************************************************************************/
extern PUBLIC bool_t bByteInArray(uint8 u8SearchByte, uint8 *pu8Array,
                                  uint8 u8ArrayLen);


/****************************************************************************/
/***        Local Functions                                               ***/
/****************************************************************************/

/****************************************************************************
 *
 * NAME: AppColdStart
 *
 * DESCRIPTION:
 * Entry point for application from boot loader. Initializes system and runs
 * main loop.
 *
 * RETURNS:
 * Never returns.
 *
 ****************************************************************************/
PUBLIC void AppColdStart(void)
{
    gMAC_u8MaxBuffers = 2;

    vAHI_WatchdogStop();

    /* General initialisation */
    vInitSystem();

    /* Initialise stack (implementation-specific command) */
    if (bRF4CE_ImpInit(NODE_CAPABILITY, VENDOR_ID, (uint8*)VENDOR_STRING))
    {
        vPrintf("\nColdStart");
        eState = E_COLD_START;
    }
    else
    {
        vPrintf("\nWarmStart");
        eState = E_WARM_START;
    }

    vAHI_TickTimerIntEnable(TRUE);
    /* Go to idle loop */
    vIdleLoop();
}

/****************************************************************************
 *
 * NAME: AppWarmStart
 *
 * DESCRIPTION:
 * Entry point for a wake from sleep mode with the memory contents held. We
 * are not using this mode and so should never get here.
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void AppWarmStart(void)
{
    AppColdStart();
}

/****************************************************************************
 *
 * NAME: vInitSystem
 *
 * DESCRIPTION:
 * Initialises stack and hardware.
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vInitSystem(void)
{

    /* Initialise stack and hardware interfaces. */
    (void)u32AHI_Init();

    /* Set clock to CPU_FREQUENCY_MHz and OptimiseWaitState */
    bAHI_SetClockRate((CPU_FREQUENCY_MHz == 32)? 3 : 2);
    vAHI_OptimiseWaitStates();

    while(bAHI_Clock32MHzStable() == FALSE);

    /* Initialise tick timer to give periodic interrupt */
    vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_DISABLE);
    vAHI_TickTimerWrite(0);
    vAHI_TickTimerRegisterCallback(vTimerISR);
    vAHI_TickTimerInterval(16 * 100000); /* 100ms tick from 16MHz Clock source */
    vAHI_TickTimerConfigure(E_AHI_TICK_TIMER_RESTART);

    /* Initialise UART for debug */
    vUART_printInit();

    /* Initialise buttons; if DIO8 pressed, destroy settings */
    if(bAppButtonsInitialise())
    {
        vPrintf("\nDestroy settings");
        vRF4CE_ImpDestroySettings();
    }
}

/****************************************************************************
 *
 * NAME: vIdleLoop
 *
 * DESCRIPTION: Application state machine
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vIdleLoop(void)
{
    char acString[8];
    uint8  u8i=0;

    while (1)
    {
        switch (eState)
        {
            case E_COLD_START:
                /* Cold start: reset stack and clear NIB; then start stack */
                vRF4CE_NlmeResetReq(TRUE);
                /* Stack start is asynchronous; wait for start confirmation.*/
                eState = E_WAIT_FOR_EV_START_CFM;
                vRF4CE_NlmeStartReq();
                break;

            case E_WAIT_FOR_EV_START_CFM:
                break;

            case E_WARM_START:
                /* Warm start: reset without clearing NIB */
                vRF4CE_NlmeResetReq(FALSE);

                /* Checking out RF4CE PairingTable for any active entry */
                for(u8i=0;u8i<RF4CE_NWKC_MAX_PAIRING_TABLE_ENTRIES;u8i++)
                {
                    (void)eRF4CE_NlmeGetReq(E_RF4CE_NIB_ATTR_PAIRING_TABLE,u8i,&uNibValue);
                    if(uNibValue.sPairingTableEntry.eState  == E_PAIR_ACTIVE )
                    {
                        u8PairingRef = u8i;
                        break;
                    }
                }
                /* Going to discovery process every time after power cycle. */
                eState = E_DISCOVERY;
                break;

            case E_DISCOVERY:
                vPrintf("\n<AutoDiscovery");
                /* Enter into auto discovery mode for AUTO_DISCOVERY_DURATION */
                vRF4CE_NlmeAutoDiscoveryReq(&sRecAppCap, au8RecDevTypeList,
                                            au8RecProfileIdList, u32AutoDiscDuration);
                eState = E_WAIT_FOR_EV_AUTODISC_CFM;
                break;

            case E_WAIT_FOR_EV_AUTODISC_CFM:
                break;

            case E_PAIRING:
                vPrintf(" <Pairing");
                /* Enable Rx for aplcMaxPairIndicationWaitTime */
                (void)eRF4CE_NlmeGetReq(E_RF4CE_NIB_ATTR_IN_POWER_SAVE, 0, &uNibValue);
                if(uNibValue.bInPowerSave == TRUE)
                {
                    eRF4CE_NlmeRxEnableReq(0xFFFFFF);
                }
                gu32TimerCounter = 0; /* Wait for APLC_MAX_PAIR_IND_WAIT_TIME */
                eState = E_WAIT_FOR_EV_PAIR_IND;
                break;

            case E_WAIT_FOR_EV_PAIR_IND:
                break;

            case E_WAIT_FOR_EV_PAIR_COMMSTATUS_IND:
                break;

            case E_PAIRED:
                vPrintf(" <Running-1>");
                (void)eRF4CE_NlmeGetReq(E_RF4CE_NIB_ATTR_PAIRING_TABLE, u8PairingRef, &uNibValue);
                vPrintf("\nPaired: PairRef %d; ", u8PairingRef);
                vLongToString(acString, uNibValue.sPairingTableEntry.sDstIeeeAddr.u32H);
                acString[8]='\0';
                vPrintf("MAC 0x%s",acString);
                vLongToString(acString, uNibValue.sPairingTableEntry.sDstIeeeAddr.u32L);
                acString[8]='\0';
                vPrintf("%s",acString);
                /* Save Settings */
                vRF4CE_ImpSaveSettings(E_SAVE_MODE_FULL);
                /* Set Device to run mode */
                eState = E_RUNNING;
                break;

            case E_RUNNING:
                if (APP_BUTTONS_DIO8 == u8AppButtonsRead())
                {
                    /* Wait until key is released */
                    while(APP_BUTTONS_DIO8 == u8AppButtonsRead());
                    eState = E_DISCOVERY;
                }

                /* Enable network power saving mode, if needed */
                if(ENABLE_NWK_POWER_SAVING_MODE)
                {
                    if(NWK_DUTY_CYCLE > 0)
                    {
                        (void)eRF4CE_NlmeGetReq(E_RF4CE_NIB_ATTR_IN_POWER_SAVE, 0, &uNibValue);
                        if(uNibValue.bInPowerSave != TRUE)
                        {
                            uNibValue.u32DutyCycle = NWK_DUTY_CYCLE;
                            (void)eRF4CE_NlmeSetReq(E_RF4CE_NIB_ATTR_DUTY_CYCLE, 0, &uNibValue);
                            uNibValue.u32ActivePeriod = NWK_ACTIVE_PERIOD;
                            (void)eRF4CE_NlmeSetReq(E_RF4CE_NIB_ATTR_ACTIVE_PERIOD, 0, &uNibValue);

                            eRF4CE_NlmeRxEnableReq(NWK_ACTIVE_PERIOD);
                            vPrintf(" <NetworkInPowerSaveMode>");
                        }
                    }
                }
                break;

            case E_NLDE_IND:
                /* Decode ZRC command */
                switch (uParam.sNldeDataInd.pu8Nsdu[0])
                {
                    case E_ZRC_USER_CONTROL_PRESSED:
                        switch(uParam.sNldeDataInd.pu8Nsdu[1])
                        {
                            case DISPLAY_INFO:
                                u8NumOfPairTableEntries = 0;
                                u8CurrentIndex = 0;

                                vPrintf("\n");
                                vPrintf("\n|--------PairingTable---------|");
                                vPrintf("\n| PairRef | MAC Address       |");
                                vPrintf("\n|-----------------------------|");
                                for(u8i=0; u8i<RF4CE_NWKC_MAX_PAIRING_TABLE_ENTRIES; u8i++)
                                {
                                    (void)eRF4CE_NlmeGetReq(E_RF4CE_NIB_ATTR_PAIRING_TABLE, u8i, &uNibValue);
                                    if(uNibValue.sPairingTableEntry.eState  == E_PAIR_ACTIVE )
                                    {
                                        vPrintf("\n|    %d    |",u8i);
                                        vLongToString(acString, uNibValue.sPairingTableEntry.sDstIeeeAddr.u32H);
                                        acString[8]='\0';
                                        vPrintf(" 0x%s",acString);
                                        vLongToString(acString, uNibValue.sPairingTableEntry.sDstIeeeAddr.u32L);
                                        acString[8]='\0';
                                        vPrintf("%s|",acString);
                                        u8PairTableIndex[u8NumOfPairTableEntries++] = u8i;
                                        gu32TimerCounter = 0;
                                        gbAcceptPairTableUpdate = TRUE;
                                    }
                                }
                                vPrintf("\n|-----------------------------|");
                                vPrintf("\n Press '0' to select next PairRef for removal within next %d seconds:", PAIR_TABLE_UPDATE_WINDOW);
                                vPrintf("\n    Press '1' to remove PairRef %d",
                                        u8PairTableIndex[u8CurrentIndex]);
                                eState = E_RUNNING;
                                break;

                            case ZERO_DIGIT:
                                if(gbAcceptPairTableUpdate == TRUE)
                                {
                                    gu32TimerCounter = 0;
                                    if(++u8CurrentIndex >= u8NumOfPairTableEntries)
                                    {
                                        u8CurrentIndex = 0;
                                    }
                                    vPrintf("\n    Press '1' to remove PairRef %d",
                                            u8PairTableIndex[u8CurrentIndex]);
                                }
                                else
                                {
                                    vPrintf("\nUserControlPressed: PairRef %d; CmdCode [%x]",
                                            uParam.sNldeDataInd.u8PairingRef,
                                            uParam.sNldeDataInd.pu8Nsdu[1]);
                                }
                                eState = E_RUNNING;
                                break;

                            case ONE_DIGIT:
                                if(gbAcceptPairTableUpdate == TRUE)
                                {
                                    gbAcceptPairTableUpdate = FALSE;
                                    eState = E_UNPAIR;
                                }
                                else
                                {
                                    vPrintf("\nUserControlPressed: PairRef %d; CmdCode [%x]",
                                            uParam.sNldeDataInd.u8PairingRef,
                                            uParam.sNldeDataInd.pu8Nsdu[1]);
                                    eState = E_RUNNING;
                                }
                                break;

                            default:
                                vPrintf("\nUserControlPressed: PairRef %d; CmdCode [%x]",
                                        uParam.sNldeDataInd.u8PairingRef,
                                        uParam.sNldeDataInd.pu8Nsdu[1]);
                                eState = E_RUNNING;
                                break;
                        }
                        break;

                    default:
                        break;
                }
                break;

            case E_WAIT_FOR_EV_NLDE_CFM:
                /* Waiting for transmit to complete */
                break;

            case E_UNPAIR:
                vPrintf("\n<Unpairing-%d",u8PairTableIndex[u8CurrentIndex]);
                (void)vRF4CE_NlmeUnpairReq(u8PairTableIndex[u8CurrentIndex]);
                eState = E_WAIT_FOR_EV_UNPAIR_CFM;
                break;

            case E_WAIT_FOR_EV_UNPAIR_CFM:
                break;

            case E_DISC_IND:
                /* If the requested device type field matches one of the device
                 * types listed in the au8RecDevTypeList
                 * and that at least one of the profile identifiers listed in the
                 * profile identifier list field matches one of the profile
                 * identifiers listed in the au8RecProfileIdList;
                 * issues the NLME-DISCOVERY.response and go for pairing. */
                vPrintf("\n<DiscoveryIND");

                if(bByteInArray(uParam.sNlmeDiscoveryInd.u8SearchDevType,
                                au8RecDevTypeList,
                                NUM_OF_SUPPORTED_DEVICE_TYPES) &&
                   bByteInArray(*(uParam.sNlmeDiscoveryInd.pu8OrgProfileIdList),
                                au8RecProfileIdList,
                                NUM_OF_SUPPORTED_PROFILES))
                {
                    vRF4CE_NlmeDiscoveryResp(uParam.sNlmeDiscoveryInd.eStatus,
                                             uParam.sNlmeDiscoveryInd.psSrcIeeeAddr,
                                             &sRecAppCap,
                                             au8RecDevTypeList,
                                             au8RecProfileIdList,
                                             uParam.sNlmeDiscoveryInd.u8RxLinkQuality);
                    eState = E_WAIT_FOR_EV_DISC_COMMSTATUS_IND;
                }
                else
                {
                    vPrintf("> <Running-7>");
                    eState = E_RUNNING;
                }
                break;

            case E_WAIT_FOR_EV_DISC_COMMSTATUS_IND:
                break;

            default:
                break;
        }
    }
}


/****************************************************************************
 *
 * NAME: vRF4CE_StackEvent
 *
 * DESCRIPTION:
 * RF4CE stack event handling. Do not overload this function.
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PUBLIC void vRF4CE_StackEvent(teRF4CE_EventType eEvent,
                              tuRF4CE_EventParam *puParam)
{
    switch (eEvent)
    {
        case E_RF4CE_EV_START_CFM:      /* Use with tsRF4CE_NlmeStartCfm */
            if (E_RF4CE_STATUS_SUCCESS == puParam->sNlmeStartCfm.eStatus)
            {
                /* nlme start successful: */
                /* Set info in NIB: nwkIndicateDiscoveryRequests to TRUE */
                uNibValue.bIndicateDiscoveryRequests = TRUE;
                (void)eRF4CE_NlmeSetReq(E_RF4CE_NIB_ATTR_IND_DISC_REQUESTS, 0, &uNibValue);

                /* Set info in NIB: user string */
                memset(uNibValue.au8UserString, 0, RF4CE_USER_STRING_LEN);
                memcpy(uNibValue.au8UserString, USER_STRING, USER_STRING_LEN);
                (void)eRF4CE_NlmeSetReq(E_RF4CE_NIB_ATTR_USER_STRING, 0, &uNibValue);

                /* Set info in NIB: nwkDiscoveryLQIThreshold to valid value,
                 * instead of default 0xFF */
                uNibValue.u8DiscoveryLqiThreshold = NIB_ATTR_NWK_DISC_LQI_THRESHOLD;
                (void)eRF4CE_NlmeSetReq(E_RF4CE_NIB_ATTR_DISC_LQI_THRESHOLD,0,&uNibValue);

                /* Go for discovery */
                eState = E_DISCOVERY;
            }
            else
            {
                /* nlme start failure: Try again */
                vRF4CE_NlmeStartReq();
            }
            break;

        case E_RF4CE_EV_AUTODISC_CFM:   /* Use with tsRF4CE_NlmeAutoDiscoveryCfm */
            if (E_RF4CE_STATUS_SUCCESS == puParam->sNlmeAutoDiscoveryCfm.eStatus)
            {
                /* Device discovered: go for pairing */
                vPrintf(">");
                eState = E_PAIRING;
            }
            else
            {
                /* Device not discovered: */
                vPrintf("> <Running-2>");
                eState = E_RUNNING;
            }
            break;

        case E_RF4CE_EV_PAIR_IND:       /* Use with tsRF4CE_NlmePairInd */
            if (E_WAIT_FOR_EV_PAIR_IND == eState)
            {
                eState = E_WAIT_FOR_EV_PAIR_COMMSTATUS_IND;
                /* Decision to accept or reject pair is outside scope of spec. */
                vRF4CE_NlmePairResp(E_RF4CE_STATUS_SUCCESS,
                                    puParam->sNlmePairInd.u16SrcPanId,
                                    puParam->sNlmePairInd.psSrcIeeeAddr,
                                    &sRecAppCap,
                                    au8RecDevTypeList,
                                    au8RecProfileIdList,
                                    puParam->sNlmePairInd.u8ProvPairingRef);
            }
            break;

        case E_RF4CE_EV_COMMSTATUS_IND: /* Use with tsRF4CE_NlmeCommStatusInd */
            if (E_RF4CE_STATUS_SUCCESS == puParam->sNlmeCommStatusInd.eStatus)
            {
                if(eState == E_WAIT_FOR_EV_PAIR_COMMSTATUS_IND)
                {
                    u8PairingRef = puParam->sNlmeCommStatusInd.u8PairingRef;
                    vPrintf(">");
                    eState = E_PAIRED;
                }
                else if(eState == E_WAIT_FOR_EV_DISC_COMMSTATUS_IND)
                {
                    vPrintf(">");
                    eState = E_PAIRING;
                }
                else
                {
                    eState = E_RUNNING;
                    vPrintf("> <Running-3a>");
                }
            }
            else
            {
                eState = E_RUNNING;
                vPrintf("> <Running-3b>");
            }
            break;

        case E_RF4CE_EV_NLDE_CFM:       /* Use with tsRF4CE_NldeDataCfm */
            if (E_WAIT_FOR_EV_NLDE_CFM == eState)
            {
                eState = E_RUNNING;
            }
            break;

        case E_RF4CE_EV_NLDE_IND:       /* Use with tsRF4CE_NldeDataInd */
            if(eState == E_RUNNING)
            {
                /* Copy sNldeDataInd and process inside vIdleLoop() to unblock
                 * underlying RF4CE core stack as soon as possible */
                memcpy(&uParam.sNldeDataInd, &(puParam->sNldeDataInd), sizeof(tsRF4CE_NldeDataInd));
                eState = E_NLDE_IND;
            }
            break;

        case E_RF4CE_EV_UNPAIR_CFM:     /* Use with tsRF4CE_NlmeUnpairCfm */
            /* Save Settings */
            vRF4CE_ImpSaveSettings(E_SAVE_MODE_FULL);
            vPrintf("> <Running-4>");
            eState = E_RUNNING;
            break;

        case E_RF4CE_EV_DISC_IND:       /* Use with tsRF4CE_NlmeDiscoveryInd */
            #if (ALWAYS_OPEN_FOR_PAIRING == TRUE)
                if(eState == E_RUNNING)
                {
                    /* Copy sNlmeDiscoveryInd and process inside vIdleLoop() to
                     * unblock underlying RF4CE core stack as soon as possible */
                    memcpy(&uParam.sNlmeDiscoveryInd, &(puParam->sNlmeDiscoveryInd), sizeof(tsRF4CE_NlmeDiscoveryInd));
                    eState = E_DISC_IND;
                }
            #endif
            break;

        case E_RF4CE_EV_UNPAIR_IND:     /* Use with tsRF4CE_NlmeUnpairInd */
        case E_RF4CE_EV_DISC_CFM:       /* Use with tsRF4CE_NlmeDiscoveryCfm */
        case E_RF4CE_EV_PAIR_CFM:       /* Use with tsRF4CE_NlmePairInd */
        default:
            break;
        }
}

/****************************************************************************
 *
 * NAME: vTimerISR
 *
 * DESCRIPTION:
 * Tick timer interrupt service routine.
 * Configured to occur at every 100ms in vInitSystem() funciton.
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vTimerISR(uint32 u32Device, uint32 u32ItemBitmap)
{
    gu32TimerCounter++;

    if((gu32TimerCounter >= (PAIR_TABLE_UPDATE_WINDOW*10)) &&
       (gbAcceptPairTableUpdate == TRUE))
    {
        gbAcceptPairTableUpdate = FALSE;
        vPrintf("\n<Running-5>");
    }

    if((eState == E_WAIT_FOR_EV_PAIR_IND) &&
        (gu32TimerCounter >= APLC_MAX_PAIR_IND_WAIT_TIME*10))
    {
        vPrintf("-TimeOut> <Running-6>");
        eState = E_RUNNING;
    }
}

/****************************************************************************
 *
 * NAME: vLongToString
 *
 * DESCRIPTION:
 * Converts an 16-bit value to a string of the textual decimal representation.
 * Adds a text string after the text.
 *
 * PARAMETERS:      Name            RW  Usage
 *                  pcOutString     R   Location for new string
 *                  u16Num          R   Value to convert
 *
 * RETURNS:
 * void
 *
 ****************************************************************************/
PRIVATE void vLongToString(char * str, uint32 u32Num)
{
    uint8 u8Nybble;
    int i;
    for (i = 28; i >= 0; i -= 4)
    {
        u8Nybble = (uint8)((u32Num >> i) & 0x0f);
        u8Nybble += 0x30;
        if (u8Nybble > 0x39)
            u8Nybble += 7;

        *str = u8Nybble;
        str++;
    }
}

/****************************************************************************/
/***        END OF FILE                                                   ***/
/****************************************************************************/
