/******************************************************************************
 *
 *  <:copyright-BRCM:2016:DUAL/GPL:standard
 *
 *     Copyright (c) 2016 Broadcom
 *     All Rights Reserved
 *
 *  Unless you and Broadcom execute a separate written software license
 *  agreement governing use of this software, this software is licensed
 *  to you under the terms of the GNU General Public License version 2
 *  (the "GPL"), available at http://www.broadcom.com/licenses/GPLv2.php,
 *  with the following added to such license:
 *
 *     As a special exception, the copyright holders of this software give
 *     you permission to link this software with independent modules, and
 *     to copy and distribute the resulting executable under terms of your
 *     choice, provided that you also meet, for each linked independent
 *     module, the terms and conditions of the license of that module.
 *     An independent module is a module which is not derived from this
 *     software.  The special exception does not apply to any modifications
 *     of the software.
 *
 *  Not withstanding the above, under no circumstances may you combine
 *  this software in any way with any other Broadcom software provided
 *  under a license other than the GPL, without Broadcom's express prior
 *  written consent.
 *
 *  :>
 *
 *****************************************************************************/

/**
 * @file acc_term_fsm.c
 * @brief Code to support the BAL access terminal FSM
 *
 * @addtogroup access_terminal
 */

/*@{*/

#define BAL_DBG_PRINT

/*--- project includes ---*/
#include <bcmos_system.h>
#include <acc_term_fsm.h>
#include <bal_msg.h>
#include <bal_api.h>
#include "bal_worker.h"
#include "bal_mac_util.h"
#include "bal_switch_util.h"
#include <bal_osmsg.h>
#include <fsm_common.h>
#include <rsc_mgr.h>
#include <bal_core.h>

#ifdef ENABLE_LOG
#include <bcm_dev_log.h>

/*
 * @brief The logging device ids for the access-terminal and interface
 */
static dev_log_id log_id_access_terminal;
static dev_log_id log_id_interface;
#endif


/*--- local function declarations  ---*/
static bcmos_errno acc_term_fsm_acc_term_admin_up_ok(acc_term_inst *p_acc_term_inst,
                                                     void *msg,
                                                     acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_acc_term_admin_dn_start(acc_term_inst *p_acc_term_inst,
                                                        void *msg,
                                                        acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_acc_term_admin_dn_ok(acc_term_inst *p_acc_term_inst,
                                                     void *msg,
                                                     acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_ignore_msg(acc_term_inst *p_acc_term_inst,
                                           void *msg,
                                           acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_acc_term_admin_up_pending(acc_term_inst *p_acc_term_inst,
                                                          void *msg,
                                                          acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_acc_term_admin_dn_pending(acc_term_inst *p_acc_term_inst,
                                                          void *msg,
                                                          acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_adding_process_util_msg(acc_term_inst *p_acc_term_inst,
                                                       void *msg,
                                                       acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_removing_process_util_msg(acc_term_inst *p_acc_term_inst,
                                                         void *msg,
                                                         acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_process_util_auto_msg(acc_term_inst *p_acc_term_inst,
                                                     void *msg,
                                                     acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_process_adding_timeout(acc_term_inst *p_acc_term_inst,
                                                       void *msg,
                                                       acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_process_removing_timeout(acc_term_inst *p_acc_term_inst,
                                                         void *msg,
                                                         acc_term_fsm_event *p_event);

static bcmos_errno acc_term_fsm_acc_term_admin_up_start(acc_term_inst *p_acc_term_inst,
                                                        void *msg,
                                                        acc_term_fsm_event *p_event);

static bcmos_errno interface_admin_up_start(acc_term_interface *p_interface,
                                            void *msg);

static bcmos_errno interface_admin_dn_start(acc_term_interface *p_interface,
                                            void *msg);

static bcmos_timer_rc acc_term_fsm_timer_expiry(bcmos_timer *timer, long pUser);

static bcmos_errno access_terminal_fsm_exec(acc_term_inst *p_acc_term_inst, acc_term_fsm_event *p_event);


/**
 * access-terminal FSM helper functions
 */
static bcmos_errno acc_term_fsm_state_err(acc_term_inst *p_acc_term_inst,
                                          void *msg,
                                          acc_term_fsm_event *p_event);

static void initialize_access_terminal_instance_config(acc_term_inst *p_acc_term_inst);

static bcmos_errno sub_term_id_list_fill(uint32_t interface_index,
                                         bcmbal_sub_id_list_u16 *sub_term_id_list);


static acc_term_inst *access_terminal_get(void);
static char *interface_type_str_get(bcmbal_intf_type intf_type);

static bcmos_errno interface_tm_sched_set(bcmbal_interface_cfg *p_interface_info);
static acc_term_interface * bcmbal_interface_get(bcmbal_interface_key key);

#define ACC_TERM_FSM_STATE_ADDING_TIMEOUT           (45) /* Seconds */

/*
 * @brief The definition of an access terminal FSM state processing function
 */
typedef bcmos_errno (* acc_term_fsm_state_processor)(acc_term_inst *, void *, acc_term_fsm_event *);

extern bcmbal_config_params bal_config_params;


/**
 * @brief API to get oper status from admin state of an interface
 */
bcmbal_status bcmbal_get_intf_oper_status_from_admin_state (bcmbal_state intf_admin_state)
{
    switch (intf_admin_state)
    {
        case BCMBAL_STATE_UP:
            return BCMBAL_STATUS_UP;
            break;

        case BCMBAL_STATE_DOWN:
            return BCMBAL_STATUS_DOWN;
            break;

        case BCMBAL_STATE_TESTING:
            return BCMBAL_STATUS_TESTING;
            break;

        default:
            return BCMBAL_STATUS_UP;  /* default keep oper status as UP */
            break;
    }

    return BCMBAL_STATUS_UP;  /* default keep oper status as UP */
}


/**
 * @brief API to convert port type and id from CLI/Mgmt interface to the internal
 * index of interface array database.
 */
uint32_t bcmbal_port_type_and_id_to_interface_index (bcmbal_intf_type intf_type, bcmbal_intf_id intf_id)
{
    switch (intf_type)
    {
        case BCMBAL_INTF_TYPE_PON:
            if (intf_id < NUM_SUPPORTED_SUBSCRIBER_INTERFACES)
            {
                return intf_id; /* zero offset for the PON ports */
            }
            break;

        case BCMBAL_INTF_TYPE_NNI:
            if (intf_id < bal_config_params.num_nni_ports)
            {
                return (NUM_SUPPORTED_SUBSCRIBER_INTERFACES + intf_id); /* offset-ed for the NNI ports */
            }
            break;

        default:
            break;
    }

    return INVALID_INTERFACE_INDEX;

}


/*
 * @brief The Access terminal FSM state processing array
 */
static acc_term_fsm_state_processor access_term_states[ACC_TERM_FSM_STATE__NUM_OF][ACC_TERM_FSM_EVENT_TYPE__NUM_OF] =
{

    [ACC_TERM_FSM_STATE_NULL] =
    {
        /*
         * Next state: ADDING
         */
        [ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP]     = acc_term_fsm_acc_term_admin_up_start,

        /*
         * Next state: NULL
         */
        [ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN]     = acc_term_fsm_acc_term_admin_dn_ok,

        /*
         * Next state: NULL
         */
        [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG]               = acc_term_fsm_ignore_msg,

        /*
         * Next state: NULL
         */
        [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG]          = acc_term_fsm_process_util_auto_msg,
    },

    [ACC_TERM_FSM_STATE_ADDING] =
    {
        /*
         * Next state: ADDING
         */
        [ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP]     = acc_term_fsm_acc_term_admin_up_pending,

        /*
         * Next state: ADDING | ADDED
         */
        [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG]               = acc_term_fsm_adding_process_util_msg,

        /*
         * Next state: ADDING
         */
        [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG]          = acc_term_fsm_process_util_auto_msg,

        /*
         * Next state: NULL
         */
        [ACC_TERM_FSM_EVENT_TYPE_TIMEOUT]               = acc_term_fsm_process_adding_timeout,

    },

    [ACC_TERM_FSM_STATE_ADDED] =
    {
        /*
         * Next state: ADDED
         */
        [ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP]     = acc_term_fsm_acc_term_admin_up_ok,

        /*
         * Next state: REMOVING
         */
        [ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN]     = acc_term_fsm_acc_term_admin_dn_start,

        /*
         * Next state: ADDING | ADDED
         */
        [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG]               = acc_term_fsm_ignore_msg,

        /*
         * Next state: ADDED
         */
        [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG]          = acc_term_fsm_process_util_auto_msg,

    },

    [ACC_TERM_FSM_STATE_REMOVING] =
    {
        /*
         * Next state: REMOVING
         */
        [ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN]     = acc_term_fsm_acc_term_admin_dn_pending,

         /*
         * Next state: REMOVING | NULL
         */
        [ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG]               = acc_term_fsm_removing_process_util_msg,

        /*
         * Next state: REMOVING
         */
        [ACC_TERM_FSM_EVENT_TYPE_UTIL_AUTO_MSG]          = acc_term_fsm_process_util_auto_msg,

        /*
         * Next state: NULL
         */
        [ACC_TERM_FSM_EVENT_TYPE_TIMEOUT]               = acc_term_fsm_process_removing_timeout,
    },

};

static char *state_name_str[] =
{
    "ACC_TERM_NULL",
    "ACC_TERM_ADDING",
    "ACC_TERM_ADDED",
    "ACC_TERM_REMOVING",
};

/* Ensure that the name array size matches the associated enum */
BAL_STATIC_ASSERT (ACC_TERM_FSM_STATE__LAST == (sizeof (state_name_str) / sizeof (char *)), acc_term_fsm_state);

static char *acc_term_state_name_get(acc_term_fsm_state state)
{
    if(state < ACC_TERM_FSM_STATE__LAST)
    {
        return state_name_str[state];
    }
    else
    {
        return "ACC_TERM_UNKNOWN";
    }
}

static char *event_name_str[] =
{
    "ACC_TERM_FSM_ACC_TERM_ADMIN_UP_EVENT",
    "ACC_TERM_FSM_ACC_TERM_ADMIN_DN_EVENT",
    "ACC_TERM_FSM_INT_ADMIN_UP_EVENT",
    "ACC_TERM_FSM_INT_ADMIN_DN_EVENT",
    "ACC_TERM_FSM_UTIL_MSG_EVENT",
    "ACC_TERM_FSM_UTIL_AUTO_MSG_EVENT",
    "ACC_TERM_FSM_TIMEOUT_EVENT"
};

/* Ensure that the name array size matches the associated enum */
BAL_STATIC_ASSERT (ACC_TERM_FSM_EVENT_TYPE__LAST == (sizeof (event_name_str) / sizeof (char *)), acc_term_fsm_event_type);

static char *acc_term_event_name_get(acc_term_fsm_event_type event)
{
    if(event < ACC_TERM_FSM_EVENT_TYPE__LAST)
    {
        return event_name_str[event];
    }
    else
    {
        return "ACC_TERM_EVT_UNKNOWN";
    }
}

static acc_term_inst single_access_terminal_instance;

/*****************************************************************************/
/**
 * @brief A function called to initialize the access-terminal FSM
 *        infrastructure.
 *
 *        NOTE: This is called once on startup and NOT for each FSM instance.
 *
 * @returns void
 *****************************************************************************/
void access_terminal_fsm_init(void)
{

#ifdef ENABLE_LOG
    /* Register the log ids for this FSM */
    log_id_access_terminal = bcm_dev_log_id_register("ACC_TERM", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
    BUG_ON(log_id_access_terminal == DEV_LOG_INVALID_ID);

    log_id_interface = bcm_dev_log_id_register("INTF", DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);
    BUG_ON(log_id_interface == DEV_LOG_INVALID_ID);
#endif

    /*
     * Initialize the access terminal instance structures
     */
    initialize_access_terminal_instance_config(&single_access_terminal_instance);
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing executive function
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno access_terminal_fsm_exec(acc_term_inst *p_acc_term_inst,
                                            acc_term_fsm_event *p_event)
{

    bcmos_errno ret = BCM_ERR_OK;
    acc_term_fsm_state pre_state;
    acc_term_fsm_state_processor acc_term_state_processor;

    /* Parameter checks */
    BUG_ON(NULL == p_acc_term_inst);
    BUG_ON(NULL == p_event);

    /* Record the present state before transitioning
     */
    pre_state = p_acc_term_inst->fsm_state;

    /*
     * Get the state processing function
     */
    acc_term_state_processor = access_term_states[p_acc_term_inst->fsm_state][p_event->event_type];

    /*
     * If there's a state processing function for this event and state, execute it.
     * Otherwise, process a generic error.
     */
    if (acc_term_state_processor)
    {
        ret = acc_term_state_processor(p_acc_term_inst, p_event->msg, p_event);
    } else
    {
        acc_term_fsm_state_err(p_acc_term_inst, p_event->msg, p_event);
    }

    BCM_LOG(DEBUG, log_id_access_terminal, "*** FSM exec: Event %s, State: %s --> %s\n",
           acc_term_event_name_get(p_event->event_type),
           acc_term_state_name_get(pre_state),
           acc_term_state_name_get(p_acc_term_inst->fsm_state));

    return ret;
}

bcmos_errno process_access_terminal_util_msg(void *msg_payload)
{
    acc_term_inst *p_access_terminal_inst;

    BCM_LOG(INFO, log_id_access_terminal, "ACCESS_TERMINAL indication received from util\n");

    /* Find the specified access terminal instance */
    p_access_terminal_inst = access_terminal_get();

    if (NULL != p_access_terminal_inst)
    {
        acc_term_fsm_event event;

        event.event_type = ACC_TERM_FSM_EVENT_TYPE_UTIL_MSG;
        event.msg = msg_payload;

        access_terminal_fsm_exec(p_access_terminal_inst, &event);
    }
    else
    {
        BCM_LOG(ERROR, log_id_interface, "Could not find the ACTIVE access-terminal\n");
    }

    return BCM_ERR_OK;
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing for an access-terminal
 *        admin-up command received from the BAL Public API when the specified
 *        access-terminal instance is in the admin-down state (i.e. when
 *        the access-terminal instance FSM is in the NULL state).
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_up_start(acc_term_inst *p_acc_term_inst,
                                                        void *msg,
                                                        acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_OK;
    acc_term_fsm_state old_state = p_acc_term_inst->fsm_state;

    BCM_LOG(INFO, log_id_access_terminal,
                "Received an admin UP request from BAL API - bringing access terminal up\n");

    do
    {
        /* change access terminal state to ADDING */
        p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_ADDING;

        /* start the timeout timer for the ADDING state */
        fsm_timer_start(&p_acc_term_inst->timer_info,
            p_acc_term_inst,
            acc_term_fsm_timer_expiry,
            TIMER_DURATION_IN_SEC(ACC_TERM_FSM_STATE_ADDING_TIMEOUT),
            log_id_access_terminal);

        /* Validate that the OLT SW version that the Bal was compiled against matches
         * the SW version of the actual OLT that the Bal works with. We assume that
         * Device Id 0 has the same version as all other OLT devices */
        if (!bcmbal_is_mac_in_loopback() &&
            (BCM_ERR_OK != (ret = mac_util_access_terminal_sw_version_validate((bcmolt_devid) 0))))
        {
        	BCM_LOG(ERROR, log_id_access_terminal, "mac_util_access_terminal_sw_version_validate(() failed. rc=%s\n", bcmos_strerror(ret));
        	break;
        }

        /* Core calls Mac Utils to set the access-terminal parameters using the applicable SDK calls */
        if(BCM_ERR_OK != (ret = mac_util_access_terminal_set(p_acc_term_inst, BAL_UTIL_OPER_ACC_TERM_CONNECT)))
        {
            BCM_LOG(ERROR, log_id_access_terminal, "mac_util_access_terminal_set(() failed. rc=%s\n", bcmos_strerror(ret));
            break;
        }

    }while(0);

    if(BCM_ERR_OK == ret)
    {
    	/*
    	* The access-terminal object command has succeeded.  The current object info
    	* becomes the commanded object info, except for the oper_status.  This should
    	* be done atomically
    	*/
    	memcpy(&p_acc_term_inst->current_acc_term_obj_info,
    		&p_acc_term_inst->api_req_acc_term_obj_info,
    		sizeof(p_acc_term_inst->api_req_acc_term_obj_info));

    	BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_TRUE);

    	BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
    		access_terminal,
    		oper_status,
    		BCMBAL_STATUS_DOWN);
    }
    else
    {
    	fsm_timer_stop(&p_acc_term_inst->timer_info);
    	p_acc_term_inst->fsm_state = old_state;
   	    mgmt_msg_send_balapi_ind(ret, msg, log_id_access_terminal);
    }

    return ret;
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing for an  access-terminal
 *        admin-up command from the BAL Public API when the specified
 *        access-terminal is already admin-up (i.e. when the specified
 *        access-terminal instance FSM is in the ADDED state).
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_up_ok(acc_term_inst *p_acc_term_inst,
                                                     void *msg,
                                                     acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_OK;

    BCM_LOG(DEBUG, log_id_access_terminal,
            "Received an admin UP request from BAL API - returning OK to the API"
            " - no further function\n");

    return ret;
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing for an access-terminal
 *        admin-down command received from the BAL Public API when the specified
 *        access-terminal is admin-up (i.e when the specified access-terminal
 *        instance FSM is in the ADDED state).
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_dn_start(acc_term_inst *p_acc_term_inst,
                                                        void *msg,
                                                        acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_OK;

    BCM_LOG(DEBUG, log_id_access_terminal,
            "Received an admin DOWN request from BAL API - removing the access terminal\n");

    /*
     * @todo - complete the DOWN implementation - until then, return an error
     */
    ret = BCM_ERR_NOT_SUPPORTED;

    return ret;
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing for access-terminal
 *        admin-down command from the BAL Public API when the specified
 *        access-terminal is already admin-down.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_dn_ok(acc_term_inst *p_acc_term_inst,
                                                     void *msg,
                                                     acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_OK;

    BCM_LOG(DEBUG, log_id_access_terminal,
            "Received an admin DOWN request from BAL API - returning OK to the API"
            " - no further function\n");

    return ret;
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing function to ignore a
 *        received message.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_ignore_msg(acc_term_inst *p_acc_term_inst,
                                           void *msg,
                                           acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_OK;

    BCM_LOG(DEBUG, log_id_access_terminal, "Ignoring message from BAL API \n");
    return ret;
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing function to process an
 *        access-terminal admin-up command from the BAL Public API when the
 *        specified access-terminal is in the REMOVING state.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_up_pending(acc_term_inst *p_acc_term_inst,
                                                          void *msg,
                                                          acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_OK;

    BCM_LOG(DEBUG, log_id_access_terminal,
            " Received an admin UP request from BAL API - returning UP_PENDING to the API"
            " - no further function\n");

    return ret;
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing function to process an
 *        access-terminal admin-down command from the BAL Public API when the
 *        specified access-terminal FSM is in the REMOVING state.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_acc_term_admin_dn_pending(acc_term_inst *p_acc_term_inst,
                                                          void *msg,
                                                          acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_IN_PROGRESS;

    BCM_LOG(DEBUG, log_id_access_terminal,
            " Received an admin DOWN request from BAL API"
            " - returning IN_PROGRESS to the API - no further function\n");

    return ret;
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing function to process a
 *        message from one of the BAL apps when the specified access-terminal
 *        instance FSM is in the ADDING state.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from one of
 *                         the BAL apps.
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_adding_process_util_msg(acc_term_inst *p_acc_term_inst,
                                                       void *msg,
                                                       acc_term_fsm_event *p_event)
{
    flow_fsm_state next_state = ACC_TERM_FSM_STATE_NULL;
    bcmos_errno ret;
    bal_util_msg_ind *ind_msg;

    /* Parameter checks */
    BUG_ON(NULL == p_acc_term_inst);
    BUG_ON(NULL == msg);
    BUG_ON(NULL == p_event);

    ind_msg = (bal_util_msg_ind *)msg;

    ret = ind_msg->status;

    /*
     * NOTE: AUTO_IND messages are not processed in this function,
     * so there is no need to consider them in this logic.
     */
    if(BCM_ERR_OK != ret)
    {
        BCM_LOG(ERROR, log_id_access_terminal,
                "Received an IND message from BAL UTIL (%s) during ADDING state with status %s\n",
                subsystem_str[bcmbal_sender_get(msg)],
                bcmos_strerror(ret)
                );
    }

   /*
    * Stop the indication timer
    */
   fsm_timer_stop(&p_acc_term_inst->timer_info);

   if(BCM_ERR_OK == ret)
   {
       /* Core calls Switch Utils to set the access-terminal parameters using the applicable SDK calls */
       ret = sw_util_access_terminal_set(p_acc_term_inst, BAL_UTIL_OPER_ACC_TERM_CONNECT);
       if (ret)
       {
           BCM_LOG(INFO, log_id_access_terminal,
                   "sw_util_access_terminal_set(() failed. rc=%s\n", bcmos_strerror(ret));
       }

       if(BCM_ERR_OK == ret)
       {
           uint32_t logical_pon;

           BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
                           access_terminal,
                           oper_status,
                           BCMBAL_STATUS_UP);

           /*
            * Initialize the resource manager only if at least of the PONs on the device is a GPON/XGPON/XGS/NGPON2 PON
            */
           BCM_TOPO_DEV_FOR_EACH_PON(0, logical_pon)
           {
               bcm_topo_pon_family pon_family = bcm_topo_pon_get_pon_family(logical_pon);

               if (pon_family == BCM_TOPO_PON_FAMILY_GPON)
               {
                   rsc_mgr_mac_init();
                   break;
               }
           }

           /*
            * Go to the ADDED state upon success
            */
           next_state = ACC_TERM_FSM_STATE_ADDED;


       }
       else
       {
           /* Error */
           BCM_LOG(ERROR, log_id_access_terminal,
                   " Failed in state %s;%s\n",
                   acc_term_state_name_get(p_acc_term_inst->fsm_state),
                   bcmos_strerror(ret));

           /*
            * Automatically return to the NULL state if an error occurs
            */
       }

       BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);

       /*
        * Send the indication back to the BAL public API here
        */
       mgmt_msg_send_balapi_ind(ret,
                                (void *)&p_acc_term_inst->current_acc_term_obj_info.hdr,
                                log_id_access_terminal);



   }

   p_acc_term_inst->fsm_state = next_state;

   return ret;
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing function to process a
 *        message from one of the BAL apps received when the specified
 *        access-terminal instance FSM is in the REMOVING state.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from one of
 *                         the BAL apps.
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_removing_process_util_msg(acc_term_inst *p_acc_term_inst,
                                                         void *msg,
                                                         acc_term_fsm_event *p_event)
{
    bcmos_errno ret;
    bal_util_msg_ind *ind_msg;

    /* Parameter checks */
    BUG_ON(NULL == p_acc_term_inst);
    BUG_ON(NULL == msg);
    BUG_ON(NULL == p_event);

    ind_msg = (bal_util_msg_ind *)msg;

    ret = ind_msg->status;

    /*
     * NOTE: AUTO_IND messages are not processed in this function,
     * so there is no need to consider them in this logic.
     */

    if(BCM_ERR_OK != ret)
    {
        BCM_LOG(ERROR, log_id_access_terminal,
                " Received an IND message from BAL UTIL (%s) during REMOVING state\n",
                subsystem_str[bcmbal_sender_get(msg)]);
    }

    return ret;
}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing function to process an
 *        AUTO IND message from one of the BAL apps.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from one of
 *                         the BAL apps.
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_process_util_auto_msg(acc_term_inst *p_acc_term_inst,
                                                     void *msg,
                                                     acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_OK;

    /* Parameter checks */
    BUG_ON(NULL == p_acc_term_inst);
    BUG_ON(NULL == msg);
    BUG_ON(NULL == p_event);

    BCM_LOG(INFO, log_id_access_terminal,
            " Received an AUTO IND message from BAL UTIL ()\n");

    return ret;
}

/*****************************************************************************/
/**
 * @brief Interface admin-up command received from the BAL Public API when
 *        the specified interface instance is in the admin-up state.
 *
 * @note  This handler gets called for both PON and NNI type interfaces
 *
 * @param p_interface_inst Pointer to an interface instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno interface_admin_up_start(acc_term_interface *p_interface_inst,
                                            void *msg)
{
		bcmos_errno ret = BCM_ERR_OK;
		bcmbal_interface_key *key = &(p_interface_inst->api_req_int_obj_info.key);

		BCM_LOG(INFO, log_id_interface,
			" Received an INTERFACE admin UP request from BAL API"
			" - bringing interface (%s%d) UP \n",
			interface_type_str_get(key->intf_type),
			key->intf_id);

		do
		{
			bcmbal_state old_admin_state = p_interface_inst->current_int_obj_info.data.admin_state;

			/*
			* Create a pointer to the interface instance specified by the user
			*/

			/*
			* If the user has set the min_data_agg_port_id attribute for the interface, then program the resource manager
			* with this value.	It will also be sent to the MAC device for any required programming there.
			*/
			if ((BCMBAL_INTF_TYPE_PON == key->intf_type) &&
				(BCMOS_TRUE == BCMBAL_CFG_PROP_IS_SET(&p_interface_inst->api_req_int_obj_info,
				interface,
				min_data_agg_port_id)) &&
				(BCM_ERR_OK != rsc_mgr_access_int_base_alloc_id_set(key->intf_id,
				p_interface_inst->api_req_int_obj_info.data.min_data_agg_port_id)))
				{
					BCM_LOG(ERROR, log_id_access_terminal, "Error while setting base agg_port_id (%d) in the resource manager\n",
						p_interface_inst->api_req_int_obj_info.data.min_data_agg_port_id);

					ret = BCM_ERR_INTERNAL;
					break;
				}

			/* Change the interface admin state of the "current" interface object to up (this is for reporting) */
			BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
				interface,
				admin_state,
				BCMBAL_STATE_UP);

			/* Core calls Mac Utils to set the interface parameters using the applicable SDK calls */
			ret = mac_util_interface_set(p_interface_inst, BAL_UTIL_OPER_IF_UP);

			if (BCM_ERR_OK != ret)
			{
				BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
					interface,
					admin_state,
					old_admin_state);

				BCM_LOG(ERROR, log_id_interface,
					"Error detected by mac_util_interface_set (%s)\n",
					bcmos_strerror(ret));

				break;
			}
		} while (0);

		if (BCM_ERR_OK != ret)
		{
			/* report this error to the API */
			mgmt_msg_send_balapi_ind(ret,
				msg,
				log_id_interface);
		}
		else
		{
			BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_TRUE);
		}

		return ret;
	}

/*****************************************************************************/
/**
 * @brief Interface admin-up command received from the BAL Public API when
 *        the specified interface instance is in the admin-down state.
 *
 * @note  This handler gets called for both PON and NNI type interfaces
 *
 * @param p_interface_inst Pointer to an interface instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno interface_admin_dn_start(acc_term_interface *p_interface_inst,
                                            void *msg)
{

    bcmos_errno ret = BCM_ERR_OK;
    bcmbal_interface_key *key = &(p_interface_inst->api_req_int_obj_info.key);

    BCM_LOG(INFO, log_id_interface,
            " Received an INTERFACE admin DOWN request from BAL API"
            " - bringing interface (%s%d) DOWN \n",
            interface_type_str_get(key->intf_type),
            key->intf_id);

    do
    {
        bcmbal_state old_admin_state = p_interface_inst->current_int_obj_info.data.admin_state;

        /*
         * Create a pointer to the interface instance specified by the user
         */

       /* Core calls Mac Utils to set the interface parameters using the applicable SDK calls */
        ret = mac_util_interface_set(p_interface_inst, BAL_UTIL_OPER_IF_DOWN);

        if (BCM_ERR_OK != ret)
        {

            BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
                            interface,
                            admin_state,
                            old_admin_state);

            BCM_LOG(ERROR, log_id_interface,
                    "Error detected by mac_util_interface_set (%s)\n",
                    bcmos_strerror(ret));

            break;
        }
		
    } while (0);

    /* Change the interface admin state of the current interface info to down */
    BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
                        interface,
                        admin_state,
                        BCMBAL_STATE_DOWN);

    /* Check for any error and send an indication immediately in that case */
    if (BCM_ERR_OK != ret)
    {
        /* report this error to the API */
        mgmt_msg_send_balapi_ind(ret,
                                 msg,
                                 log_id_interface);

    }
    else
    {
        BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_TRUE);
    }

    return ret;

}

/*****************************************************************************/
/**
 * @brief The function to process a timer expiry for either the ADDING
 *        states.  This function executes an
 *        ACC_TERM_FSM_TIMEOUT_EVENT in the FSM state machine.
 *
 * @param timer - A pointer to the timer instance
 * @param pUser - An opaque pointer to an access terminal instance
 *
 * @returns bcmos_timer_rc == BCMOS_TIMER_OK
 */
static bcmos_timer_rc acc_term_fsm_timer_expiry(bcmos_timer *timer, long pUser)
{
    acc_term_fsm_event acc_term_event;

   /*
    * Stop the indication timer
    */
    fsm_timer_stop(timer);

    BCM_LOG(INFO, log_id_access_terminal,
            "timer expiry\n");

    /*
     * A message pointer is always passed inside the event structure. In this case, it is unused
     */
    acc_term_event.msg = NULL;
    acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_TIMEOUT;

    /* Declare this no longer in-progress */
    BCMBAL_OBJ_IN_PROGRESS_SET(&(((acc_term_inst *)pUser)->current_acc_term_obj_info), BCMOS_FALSE);

    /*
     * Run the access terminal FSM to process this event
     */
    access_terminal_fsm_exec((acc_term_inst *)pUser, &acc_term_event);

    return BCMOS_TIMER_OK;

}


/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing a timeout that occurs
 *        when the FSM is in the ADDING state. In this case, the FSM should
 *        just go back to the NULL state.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_process_adding_timeout(acc_term_inst *p_acc_term_inst,
                                                       void *msg,
                                                       acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_OK;

    BCM_LOG(ERROR, log_id_access_terminal,
            "Error: Received a timeout while in the %s state.\n",
            acc_term_state_name_get(p_acc_term_inst->fsm_state));


    /*
     * Send the indication back to the BAL public API here
     */
    mgmt_msg_send_balapi_ind(BCM_ERR_TIMEOUT,
                             (void *)&(p_acc_term_inst->current_acc_term_obj_info.hdr.hdr),
                             log_id_access_terminal);

    /*
     * Go back to the previous state
     */
    p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_NULL;
    BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);

    return ret;

}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM state processing a timeout that occurs
 *        when the FSM is in the REMOVING state. In this case, the FSM should
 *        just go back to the ADDED state.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message received from the BAL Public API
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_process_removing_timeout(acc_term_inst *p_acc_term_inst,
                                                         void *msg,
                                                         acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_OK;

    BCM_LOG(INFO, log_id_access_terminal,
            "Received a timeout while in the %s state.  Going back to the ADDED state\n",
             acc_term_state_name_get(p_acc_term_inst->fsm_state));

    /*
     * Go back to the previous state
     */
    p_acc_term_inst->fsm_state = ACC_TERM_FSM_STATE_ADDED;

    return ret;

}

/*****************************************************************************/
/**
 * @brief The function to process a
 *        message from one of the BAL apps for the specified interface
 *
 * @param msg              Pointer to a BAL message received from one of
 *                         the BAL apps.
 *
 * @returns bcmos_errno
 *****************************************************************************/
bcmos_errno process_interface_util_msg(void *msg)
{
    bcmos_errno   ret = BCM_ERR_OK;
    uint32_t interface_index = INVALID_INTERFACE_INDEX;
    bal_util_msg_ind *ind_msg;
    acc_term_interface *p_interface_inst;

    /* Parameter checks */
    BUG_ON(NULL == msg);

    ind_msg = (bal_util_msg_ind *)msg;

    /*
     * NOTE: AUTO_IND messages are not processed in this function,
     * so there is no need to consider them in this logic.
     */
    BCM_LOG(DEBUG, log_id_access_terminal,
            " Received an interface IND message from BAL UTIL (%s)\n",
            subsystem_str[bcmbal_sender_get(msg)]);

    if (BCM_ERR_OK == ind_msg->status)
    {
        /* first get the index to the interface array from port id/type */
        interface_index = bcmbal_port_type_and_id_to_interface_index(ind_msg->obj_key.if_key.intf_type,
                                                                     ind_msg->obj_key.if_key.intf_id);

        if (interface_index >= INVALID_INTERFACE_INDEX)
        {
            BCM_LOG(ERROR, log_id_interface,
                    "INVALID port type/id (%s/%d) to interface index (%d)\n",
                    interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
                    ind_msg->obj_key.if_key.intf_id,
                    interface_index);

            ret = BCM_ERR_PARM;
        }

        p_interface_inst = &(access_terminal_get()->intf_info.interface[interface_index]);

        if(BCM_ERR_OK == ret)
        {
            /* Core calls Switch Utils to set the interface parameters using the applicable SDK call
             * If a PON port is being set, then the corresponding direct connect switch port is also
             * set along with it
             */
            ret = sw_util_interface_set(p_interface_inst,
                                        (p_interface_inst->api_req_int_obj_info.data.admin_state == BCMBAL_STATE_DOWN ?
                                         BAL_UTIL_OPER_IF_DOWN : BAL_UTIL_OPER_IF_UP));

            if (ret)
            {
                BCM_LOG(ERROR, log_id_access_terminal,
                        "sw_util_interface_set(() failed. rc=%s\n", bcmos_strerror(ret));

            }
        }
        else
        {
            /* Error */
            BCM_LOG(ERROR, log_id_interface,
                    "Bad interface index: interface type/id (%s/%d) (status: %s)\n",
                    interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
                    ind_msg->obj_key.if_key.intf_id,
                    bcmos_strerror(ind_msg->status));
        }



        if(BCM_ERR_OK == ret)
        {
            BCM_LOG(DEBUG, log_id_interface,
                    "Setting interface (%d) to %s\n",
                    interface_index,
                    (BCMBAL_STATE_UP == p_interface_inst->api_req_int_obj_info.data.admin_state) ?
                    "UP" : "DOWN");


            /*
             * Interface SET function succeeded, so copy the API request into the
             * current interface object.
             */
             
			bcmbal_interface_object_overlay_w_src_priority(&(p_interface_inst->current_int_obj_info),&(p_interface_inst->api_req_int_obj_info));

            /* Set the status of the current interface that we just configured to the requested state (UP or DOWN) */
            BCMBAL_CFG_PROP_SET(&p_interface_inst->current_int_obj_info,
                                interface,
                                oper_status,
                                bcmbal_get_intf_oper_status_from_admin_state(p_interface_inst->api_req_int_obj_info.data.admin_state));

        }
        else
        {
            /* Error */
            BCM_LOG(ERROR, log_id_interface,
                    "Bad response from switch: Interface type/Id: %s/%d (status:%s) \n",
                    interface_type_str_get(ind_msg->obj_key.if_key.intf_type),
                    ind_msg->obj_key.if_key.intf_id,
                    bcmos_strerror(ind_msg->status));

        }
    }
    else
    {
        /* Error */
        BCM_LOG(ERROR, log_id_interface,
                "Bad interface indication from MAC (status:%s)\n",
                bcmos_strerror(ind_msg->status));
    }

    BCMBAL_OBJ_IN_PROGRESS_SET(&(p_interface_inst->current_int_obj_info), BCMOS_FALSE);

    /*
     * Send the indication back to the BAL public API here
     */
    mgmt_msg_send_balapi_ind(ret,
                             (void *)&(p_interface_inst->current_int_obj_info.hdr),
                             log_id_interface);

    return ret;

}

/*****************************************************************************/
/**
 * @brief The Access terminal FSM function which is executed when an error
 *        is encountered during FSM processing.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 * @param msg              Pointer to a BAL message (MAY BE NULL!)
 * @param p_event          Pointer to an access terminal event structure
 *
 * @returns bcmos_errno
 *****************************************************************************/
static bcmos_errno acc_term_fsm_state_err(acc_term_inst *p_acc_term_inst,
                                          void *msg,
                                          acc_term_fsm_event *p_event)
{
    bcmos_errno ret = BCM_ERR_INVALID_OP;

    BCM_LOG(ERROR, log_id_access_terminal,
            "Error encountered processing FSM - BAD EVENT   event:%s, state:%s\n",
            acc_term_event_name_get(p_event->event_type),
            acc_term_state_name_get(p_acc_term_inst->fsm_state));

    return ret;
}


/*****************************************************************************/
/**
 * @brief A function called by the core worker thread to process an
 *        access-terminal object message (SET, GET, CLEAR, STATS) received
 *        from the BAL Public API.
 *
 * @param msg_payload      Pointer to a BAL message received from the
 *                         BAL Public API.
 *
 * @returns bcmos_errno
 *****************************************************************************/
bcmos_errno process_access_terminal_object(void *msg_payload)
{

    bcmos_errno ret = BCM_ERR_OK, rsp_ret = BCM_ERR_OK;
    acc_term_inst *p_access_terminal_inst;
    acc_term_fsm_event acc_term_event;
    bcmbal_obj_msg_type oper_type;

    /* Parameter checks */
    BUG_ON(NULL == msg_payload);

    BCM_LOG(DEBUG, log_id_access_terminal,
            "Processing an access-terminal object\n");

    do
    {
        /*
         * Find or create the specified access terminal instance
         */
        p_access_terminal_inst = access_terminal_get();

        oper_type = ((bcmbal_access_terminal_cfg *)msg_payload)->hdr.hdr.type;

        /* If the state of the access-terminal is in flux, then reject the SET request */
        if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
           BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(&(p_access_terminal_inst->current_acc_term_obj_info)))
        {
              BCM_LOG(ERROR, log_id_access_terminal,
                        "The access-terminal is in-progress, SETs are not allowed\n");
              ret = BCM_ERR_IN_PROGRESS;
            break;
        }

        /* Copy the object in the message into local storage */
        memcpy(&p_access_terminal_inst->api_req_acc_term_obj_info,
               msg_payload,
               sizeof(p_access_terminal_inst->api_req_acc_term_obj_info));

        BCM_LOG(DEBUG, log_id_access_terminal,
                "access_terminal admin state is: %s\n",
                (BCMBAL_STATE_UP == p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state) ?
                "UP" : "DOWN");

        /*
         * A message pointer is always passed inside the event structure.
         */
        acc_term_event.msg = msg_payload;

        /* SET or GET or ...? */
        switch (oper_type)
        {
            case (BCMBAL_OBJ_MSG_TYPE_SET):
            {

                BCM_LOG(DEBUG, log_id_access_terminal,
                        "Processing a access-terminal SET REQ mgmt message\n");

                /*
                 * Check if the mandatory access-terminal attributes have been set
                 */

                do
                {

                    /* The admin state attribute is mandatory */
                    if(BCMOS_FALSE == BCMBAL_CFG_PROP_IS_SET(&p_access_terminal_inst->api_req_acc_term_obj_info,
                                                         access_terminal,
                                                         admin_state))
                    {
                        ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
                        break;
                    }

                    /*set iwf_mode from the global config parameters*/
                    BCMBAL_CFG_PROP_SET(&p_access_terminal_inst->api_req_acc_term_obj_info,
                                    access_terminal,
                                    iwf_mode,
                                    bcmbal_config_get()->iwf_mode);

                    /*
                     * Perform the validation check(s) that the utils require
                     */
                    if(BCM_ERR_OK !=
                       (ret = mac_util_access_terminal_info_validate(&p_access_terminal_inst->api_req_acc_term_obj_info)))
                    {
                        break;
                    }
                }
                while(0);

                /* We respond to the BAL public API backend with a result. We always
                 * send a complete msg_payload back to the API, but the data portion
                 * of the object is only relevant when a GET or GET-STATS has been requested.
                 */
                rsp_ret = mgmt_msg_send_balapi_rsp(ret,
                                                   msg_payload,
                                                   oper_type,
                                                   log_id_access_terminal);

                if(BCM_ERR_OK != rsp_ret || BCM_ERR_OK != ret)
                {
                    /* the mgmt_msg_send_balapi_rsp function above logs any errors that occur there */
                    ret = (BCM_ERR_OK != rsp_ret) ? rsp_ret : ret;
                    break;
                }

                /* Reflect the admin state of the access-terminal according to the commanded admin state */
                BCMBAL_CFG_PROP_SET(&p_access_terminal_inst->current_acc_term_obj_info,
                                access_terminal,
                                admin_state,
                                p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state);

                if(BCMBAL_STATE_UP == p_access_terminal_inst->api_req_acc_term_obj_info.data.admin_state)
                {

                    acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_ADMIN_UP;
                }
                else
                {
                    acc_term_event.event_type = ACC_TERM_FSM_EVENT_TYPE_ADMIN_DN;
                }

                /*
                 * Run the access terminal FSM to process this event
                 */
                ret = access_terminal_fsm_exec(p_access_terminal_inst, &acc_term_event);
                break;

            }
            case (BCMBAL_OBJ_MSG_TYPE_GET):
            {

                BCM_LOG(DEBUG, log_id_access_terminal,
                        "Processing a access-terminal GET REQ mgmt message\n");

                p_access_terminal_inst->current_acc_term_obj_info.hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;
                *((bcmbal_access_terminal_cfg *)msg_payload) = p_access_terminal_inst->current_acc_term_obj_info;

                mgmt_msg_send_balapi_rsp(ret,
                                         msg_payload,
                                         oper_type,
                                         log_id_access_terminal);
                break;

            }
            default:
            {
                BCM_LOG(ERROR, log_id_access_terminal,
                        "Unsupported operation on access-terminal object (%d)\n",
                        bcmbal_msg_id_oper_get(msg_payload));

                ret = BCM_ERR_NOT_SUPPORTED;

                /* We respond to the BAL public API backend with a result. We always
                 * send a complete msg_payload back to the API, but the data portion
                 * of the object is only relevant when a GET or GET-STATS has been requested.
                 */
                mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_access_terminal);

                break;
            }
        }
    }while(0);

    return ret;
}

/*****************************************************************************/
/**
 * @brief A function to retrieve an access-terminal instance
 *
 * @returns acc_term_inst_t*  A pointer to the found access-terminal instance,
 *                            or NULL if one is not found.
 *****************************************************************************/
static acc_term_inst *access_terminal_get(void)
{
    acc_term_inst *p_acc_term = (acc_term_inst *)NULL;

    p_acc_term = &single_access_terminal_instance;

    return p_acc_term;
}

/*****************************************************************************/
/**
 * @brief A function to retrieve the status of the access-terminal
 *
 *
 * @returns bcmbal_status
 *****************************************************************************/
bcmbal_status acc_term_status_get(void)
{
    acc_term_inst *p_acc_term_inst;

    p_acc_term_inst = access_terminal_get();

    return p_acc_term_inst->current_acc_term_obj_info.data.oper_status;

}

static bcmos_errno interface_tm_sched_set(bcmbal_interface_cfg *p_interface_info)
{
    bcmos_errno ret = BCM_ERR_OK;
    tm_sched_inst *p_tm_sched_inst;
    bcmbal_tm_sched_key tm_key;
    switch(p_interface_info->key.intf_type)
    {
        case BCMBAL_INTF_TYPE_PON:
        {
            /*for active pon interface:
                       ds_tm should be define, - if it is set, validate sched exist and match direction (ds)
                    if not set - will create auto created tm            */
            if(BCMBAL_CFG_PROP_IS_SET(p_interface_info,interface,ds_tm))
            {
                tm_key.dir = BCMBAL_TM_SCHED_DIR_DS;
                tm_key.id = p_interface_info->data.ds_tm;
                p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
                if (NULL == p_tm_sched_inst)
                {
                    BCM_LOG(ERROR, log_id_interface, "there is no ds tm sched with id %d", tm_key.id);
                    ret = BCM_ERR_NOENT;
                    break;
                }
				ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
				if(BCM_ERR_OK != ret)
				{
					BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
                           p_interface_info->key.intf_id, tm_key.id);
					break;
				}
            }
            else /*auto created sched was removed and no other default sched was set*/
            {
                BCM_LOG(ERROR, log_id_interface, "default tm node must be set! ");
                ret = BCM_ERR_MANDATORY_PARM_IS_MISSING;
                break; 				
            }			
			/* us_tm is optional - if it is set, validate sched exist and match direction (us)*/
		    if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, us_tm))
            {
                tm_key.dir = BCMBAL_TM_SCHED_DIR_US;
                tm_key.id = p_interface_info->data.us_tm;
                p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
                if (NULL == p_tm_sched_inst)
                {
                    BCM_LOG(ERROR, log_id_interface, "there is no us tm sched with id %d", tm_key.id);
                    ret = BCM_ERR_NOENT;
                    break;
                }
				ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
				if(BCM_ERR_OK != ret)
				{
					BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
                           p_interface_info->key.intf_id, tm_key.id);
					break;
				}
            }

        }
        break;

        case BCMBAL_INTF_TYPE_NNI:
        {
            /*for active nni interface:
            us_tm should be define, -
            if it is set, validate sched exist and match direction (us)
            if not set - will create auto created tm
            */
            if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, us_tm))
            {
                tm_key.dir = BCMBAL_TM_SCHED_DIR_US;
                tm_key.id = p_interface_info->data.us_tm;
                p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
                if (NULL == p_tm_sched_inst)
                {
                    BCM_LOG(ERROR, log_id_interface, "there is no us tm sched with id %d", tm_key.id);
                    ret = BCM_ERR_NOENT;
                    break;
                }

				ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
				if(BCM_ERR_OK != ret)
				{
					BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
                           p_interface_info->key.intf_id, tm_key.id);
					break;
				}
            }
            else /*auto created sched was removed and no other default sched was set*/
            {
                BCM_LOG(ERROR, log_id_interface, "default tm node must be set! ");
                break;	
            }			
 			/* ds_tm is optional - if it is set, validate sched exist and match direction (ds)*/
            if(BCMBAL_CFG_PROP_IS_SET(p_interface_info, interface, ds_tm))
            {
                tm_key.dir = BCMBAL_TM_SCHED_DIR_DS;
                tm_key.id = p_interface_info->data.ds_tm;
                p_tm_sched_inst = tm_sched_inst_get(tm_key, TM_SCHED_FLAG_ACTIVE);
                if (NULL == p_tm_sched_inst)
                {
                    BCM_LOG(ERROR, log_id_interface, "there is no ds tm sched with id %d", tm_key.id);
                    ret = BCM_ERR_NOENT;
                    break;
                }

                ret = bcmbal_tm_sched_set_interface_owner(p_interface_info->key, p_tm_sched_inst);
                if(BCM_ERR_OK != ret)
                {
                    BCM_LOG(ERROR, log_id_interface, "could not set interface %d as owner of tm sched %d",
                           p_interface_info->key.intf_id, tm_key.id);
                    break;
				}
            }
        }
        break;

        default:
            BCM_LOG(ERROR, log_id_interface, "Invalid intf type (%d) in interface key\n",
                   p_interface_info->key.intf_type);
            ret = BCM_ERR_PARM;
    }
    return ret;
}

bcmos_errno interface_tm_sched_unset(bcmbal_interface_key intf_key, bcmbal_tm_sched_key sched_key)
{
    bcmos_errno ret = BCM_ERR_OK;
    acc_term_interface *p_acc_term_interface =  bcmbal_interface_get(intf_key);
    do
    {
        if(NULL == p_acc_term_interface)
        {
            BCM_LOG(ERROR, log_id_interface, "no such interface (id = %d dir = %s ) \n",
                intf_key.intf_id, interface_type_str_get(intf_key.intf_type));
            ret = BCM_ERR_INTERNAL;
		    break;
        }
        if (BCMBAL_TM_SCHED_DIR_US == sched_key.dir)
        {
            BCMBAL_CFG_PROP_CLEAR(&(p_acc_term_interface->current_int_obj_info), interface, us_tm);
        }
        else
        {
            BCMBAL_CFG_PROP_CLEAR(&(p_acc_term_interface->current_int_obj_info), interface, ds_tm);
        }
    }while(0);
    return ret;
}


/*****************************************************************************/
/**
 * @brief A function to process an interface object message
 *        (SET, GET, CLEAR, STATS) received from the BAL Public API.
 *
 * @param msg_payload      Pointer to a BAL message received from the
 *                         BAL Public API.
 *
 * @returns bcmos_errno
 *****************************************************************************/
bcmos_errno process_interface_object(void *msg_payload)
{
    bcmos_errno ret = BCM_ERR_OK;

    bcmbal_interface_cfg *p_intf_cfg = (bcmbal_interface_cfg *)msg_payload;
    bcmbal_interface_key *p_intf_key;
    acc_term_inst *p_access_terminal_inst;

    bcmbal_interface_cfg *p_api_req_interface_info;
    bcmbal_interface_cfg *p_current_interface_info;
    uint32_t interface_index = INVALID_INTERFACE_INDEX;
    bcmbal_obj_msg_type oper_type;

    BCM_LOG(DEBUG, log_id_interface,
            "Processing an interface object\n");

    do
    {
        do
        {
            oper_type = p_intf_cfg->hdr.hdr.type;

            /*
             * See if the access terminal is active
             */
            p_access_terminal_inst = access_terminal_get();

            if(NULL == p_access_terminal_inst)
            {
                BCM_LOG(ERROR, log_id_access_terminal,
                        "the access-terminal is not active\n");

                ret = BCM_ERR_NOENT;
                break;
            }

            /* If the state of the access-terminal is in flux, then reject the SET request */
            if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
               BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(&(p_access_terminal_inst->current_acc_term_obj_info)))
            {
                BCM_LOG(ERROR, log_id_access_terminal,
                        "The access-terminal is in-progress, SETs to an interface are not allowed\n");

                ret = BCM_ERR_IN_PROGRESS;
                break;
            }

            /*
             * Get the interface key from the message
             */
            p_intf_key = &p_intf_cfg->key;

            if (p_intf_key->intf_type == BCMBAL_INTF_TYPE_PON)
            {
                if(p_intf_key->intf_id > NUM_SUPPORTED_SUBSCRIBER_INTERFACES)
                {
                    BCM_LOG(ERROR, log_id_interface,
                            "out of range value (%d) detected in interface key for PON\n", p_intf_key->intf_id);

                    ret = BCM_ERR_RANGE;
                    break;
                }
            }
            /** @todo check the lower limit also */
            else if (p_intf_key->intf_type == BCMBAL_INTF_TYPE_NNI)
            {
                if( BCMOS_FALSE == bcm_topo_nni_is_valid(p_intf_key->intf_id))
                {
                    BCM_LOG(ERROR, log_id_interface,
                            "out of range value (%d) detected in interface key for NNI\n", p_intf_key->intf_id);

                    ret = BCM_ERR_RANGE;
                    break;
                }
            }
            else
            {
                BCM_LOG(ERROR, log_id_interface,
                        "Invalid intf type (%d) in interface key\n", p_intf_key->intf_type);

                ret = BCM_ERR_PARM;
                break;
            }

            /*
             * Don't accept interface object references when the associated access-terminal is down
             *
             * Interfaces are not even instantiated internally until the access-terminal object to which
             * they belong is instantiated.
             */
            if(BCMBAL_STATE_DOWN == p_access_terminal_inst->current_acc_term_obj_info.data.admin_state)
            {
                BCM_LOG(INFO, log_id_interface,
                        "access terminal admin-state is DOWN\n");

                ret = BCM_ERR_INVALID_OP;
                break;
            }

            /* Get the index to the interface array from port id/type */
            interface_index = bcmbal_port_type_and_id_to_interface_index (p_intf_key->intf_type, p_intf_key->intf_id);
            if (interface_index >= INVALID_INTERFACE_INDEX)
            {
                BCM_LOG(ERROR, log_id_access_terminal,
                        "INVALID port type/id (%s/%d) to interface index (%d) for access terminal\n",
                        interface_type_str_get(p_intf_key->intf_type), p_intf_key->intf_id, interface_index);

                ret = BCM_ERR_PARM;
                break;
            }

            /*
             * This is a pointer to the "API interface" structure
             */
            p_api_req_interface_info =
                &(p_access_terminal_inst->intf_info.interface[interface_index].api_req_int_obj_info);

            /*
             * This is a pointer to the "current interface" structure
             */
            p_current_interface_info =
                &(p_access_terminal_inst->intf_info.interface[interface_index].current_int_obj_info);

            /* If the state of the interface is in flux, then reject the SET request */
            if(BCMBAL_OBJ_MSG_TYPE_SET == oper_type &&
               (BCMOS_TRUE == BCMBAL_OBJ_IN_PROGRESS_GET(p_current_interface_info)))
            {
                BCM_LOG(ERROR, log_id_access_terminal,
                        "The interface is in-progress, SETs are not allowed\n");
                ret = BCM_ERR_IN_PROGRESS;
                break;
            }

        }while(0);

        if(BCM_ERR_OK != ret)
        {
            /* We respond to the BAL public API backend with a result. We always
             * send a complete msg_payload back to the API, but the data portion
             * of the object is only relevant when a GET or GET-STATS has been requested.
             */
            mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
            break;
        }

        /*
         * Fill in the interface info SET data structure
         */
        *p_api_req_interface_info = *p_intf_cfg;

        BCM_LOG(DEBUG, log_id_interface,
                " interface object state from API message is: %d, intf_type: %s intf_id: %d\n",
                p_api_req_interface_info->data.admin_state,
                interface_type_str_get(p_api_req_interface_info->key.intf_type),
                p_api_req_interface_info->key.intf_id);


        /* SET or GET or ...? */
        switch (oper_type)
        {

            case (BCMBAL_OBJ_MSG_TYPE_SET):
            {
                BCM_LOG(DEBUG, log_id_interface,
                        "Processing an interface SET REQ mgmt message\n");
                /*if sched is already set, can not change sched setting using set command, should first delete current sched*/
                if(BCMBAL_CFG_PROP_IS_SET(p_current_interface_info,interface,ds_tm)
                   && BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,interface,ds_tm))
                {
                    BCM_LOG(ERROR, log_id_interface,
                            "ds_tm %d is already set at interface, it should be first cleared in order to be replaced \n",
                            p_current_interface_info->data.ds_tm);
					ret = BCM_ERR_ALREADY;
					break;
                }
                if(BCMBAL_CFG_PROP_IS_SET(p_current_interface_info,interface,us_tm)
                   && BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,interface,us_tm))
                {
                    BCM_LOG(ERROR, log_id_interface,
                            "us_tm %d is already set at interface, it should be first cleared in order to be replaced \n",
                            p_current_interface_info->data.us_tm);
                    ret = BCM_ERR_ALREADY;
                    break;
                }	
                /* We respond to the BAL public API backend with a result. We always
                 * send a complete msg_payload back to the API, but the data portion
                 * of the object is only relevant when a GET or GET-STATS has been requested.
                 */
                ret = mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);

                if(BCM_ERR_OK != ret)
                {
                    break;
                }

                /* If this interface is already up, then just return OK */
                if(BCMBAL_STATE_UP == p_api_req_interface_info->data.admin_state)
                {
                    if(BCMBAL_STATUS_UP == p_current_interface_info->data.oper_status)
                    {
                        BCM_LOG(DEBUG, log_id_interface,
                                "=====> Received an interface UP for an already UP interface, returning OK\n");
                        break;
                    }

                    /*validate and set the interface' tm sched*/
                    bcmbal_interface_object_overlay_w_dst_priority(p_api_req_interface_info,p_current_interface_info);
                    ret = interface_tm_sched_set(p_api_req_interface_info);					
                    if(BCM_ERR_OK != ret)
                    {
                        BCM_LOG(ERROR, log_id_interface,"Could not set the interface tm sched\n");
                        break;
                    }
                    interface_admin_up_start(&(p_access_terminal_inst->intf_info.interface[interface_index]),
                                                msg_payload);
                }
                else
                {
                    if(BCMBAL_STATUS_DOWN == p_current_interface_info->data.oper_status)
                    {
                        BCM_LOG(DEBUG, log_id_interface,
                                "=====> Received an interface DOWN for an already DOWN interface, returning OK\n");

                        break;
                    }

                    interface_admin_dn_start(&(p_access_terminal_inst->intf_info.interface[interface_index]),
                                             msg_payload);

                }

                break;

            }
            case (BCMBAL_OBJ_MSG_TYPE_GET):
            {

                BCM_LOG(DEBUG, log_id_interface,
                        "Processing a interface GET REQ mgmt message\n");

                /* We respond to the BAL public API backend with a result. We always
                 * send a complete msg_payload back to the API, but the data portion
                 * of the object is only relevant when a GET or GET-STATS has been requested.
                 */
                p_current_interface_info->hdr.hdr.comm_hdr = ((bcmbal_obj *)msg_payload)->comm_hdr;

                bcmbal_sub_id_list_u16 sub_term_id_list = {};

                BCMBAL_CFG_PROP_CLEAR(p_current_interface_info,
                                      interface,
                                      sub_term_id_list);

                /* If the user requested the list of sub_term_ids for this interface,
                 * and this is a PON interface, then return the list.
                 */
                if(BCMBAL_CFG_PROP_IS_SET(p_api_req_interface_info,
                                          interface,
                                          sub_term_id_list))
                {
                    if(BCMBAL_INTF_TYPE_PON == p_current_interface_info->key.intf_type)
                    {

                        sub_term_id_list_fill(interface_index, &sub_term_id_list);

                        /* NOTE: The returned list may be empty */
                        BCMBAL_CFG_PROP_SET(p_current_interface_info,
                                            interface,
                                            sub_term_id_list,
                                            sub_term_id_list);

                    }
                }

                *((bcmbal_interface_cfg *)msg_payload) = *p_current_interface_info;

                mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);

                /* Free the temporary list if it was used */
                if(sub_term_id_list.val)
                {
                    bcmos_free(sub_term_id_list.val);
                }

                break;
            }
            default:
            {
                BCM_LOG(ERROR, log_id_interface,
                        "Unsupported operation on interface object (%d)\n",
                        bcmbal_msg_id_oper_get(msg_payload));

                ret = BCM_ERR_NOT_SUPPORTED;

                /* We respond to the BAL public API backend with a result. We always
                 * send a complete msg_payload back to the API, but the data portion
                 * of the object is only relevant when a GET or GET-STATS has been requested.
                 */
                mgmt_msg_send_balapi_rsp(ret, msg_payload, oper_type, log_id_interface);
                break;
            }

        }

    }while (0);

    return ret;
}


/*****************************************************************************/
/**
 * @brief A function called to initialize a single access-terminal instance.
 *        NOTE: This is called once on startup and NOT for each FSM instance.
 *
 * @param p_acc_term_inst  Pointer to an access terminal instance
 *
 * @returns void
 *****************************************************************************/
static void initialize_access_terminal_instance_config(acc_term_inst *p_acc_term_inst)
{
    int ii;
    int intf_id;
    bcmos_errno ret;
	
    BUG_ON(NULL == p_acc_term_inst);

    p_acc_term_inst->current_acc_term_obj_info.key.access_term_id = 0;

    BCMBAL_CFG_INIT(&p_acc_term_inst->current_acc_term_obj_info,
                    access_terminal,
                    p_acc_term_inst->current_acc_term_obj_info.key);

    BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
                        access_terminal,
                        admin_state,
                        BCMBAL_STATE_DOWN);

    BCMBAL_CFG_PROP_SET(&p_acc_term_inst->current_acc_term_obj_info,
                        access_terminal,
                        oper_status,
                        BCMBAL_STATUS_DOWN);

    BCMBAL_PROP_SET_PRESENT(&p_acc_term_inst->current_acc_term_obj_info,
                            access_terminal,
                            _cfg,
                            iwf_mode);

    BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->current_acc_term_obj_info), BCMOS_FALSE);

    {
        bcmbal_interface_key key;

        intf_id = 0;    /* reset the port id to the starting id value for the PON interfaces */

        key.intf_type = BCMBAL_INTF_TYPE_PON;

        for(ii=0; ii<NUM_SUPPORTED_SUBSCRIBER_INTERFACES; ii++)
        {

            key.intf_id = intf_id;

            p_acc_term_inst->intf_info.interface[ii].num_sub_terms_on_int = 0;
            TAILQ_INIT(&p_acc_term_inst->intf_info.interface[ii].sub_term_id_list);

            BCMBAL_CFG_INIT(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
                            interface,
                            key);

            BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
                            interface,
                            admin_state,
                            BCMBAL_STATE_DOWN);

            BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
                            interface,
                            oper_status,
                            BCMBAL_STATUS_DOWN);
			
            ret = bcmbal_tm_sched_interface_tm_auto_create(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info);
            if(BCM_ERR_OK != ret)
            {
                BCM_LOG(ERROR, log_id_interface, "could not set an auto - create a tm sched for pon if %d", intf_id);
				break;
            } 

            BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->intf_info.interface[ii].current_int_obj_info), BCMOS_FALSE);

            intf_id++;
        }

        intf_id = 0;    /* reset the port id to the starting id value for the NNI interfaces */

        key.intf_type = BCMBAL_INTF_TYPE_NNI;

        for(ii=NUM_SUPPORTED_SUBSCRIBER_INTERFACES; ii<(NUM_SUPPORTED_SUBSCRIBER_INTERFACES + bal_config_params.num_nni_ports); ii++)
        {

            key.intf_id = intf_id;

            BCMBAL_CFG_INIT(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
                            interface,
                            key);

            BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
                            interface,
                            admin_state,
                            BCMBAL_STATE_UP);

            BCMBAL_CFG_PROP_SET(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info,
                            interface,
                            oper_status,
                            BCMBAL_STATUS_UP);

			
            ret = bcmbal_tm_sched_interface_tm_auto_create(&p_acc_term_inst->intf_info.interface[ii].current_int_obj_info);
            if(BCM_ERR_OK != ret)
            {
                BCM_LOG(ERROR, log_id_interface, "could not set an auto - create a tm sched for nni if %d", intf_id); 
                break;
            }

            BCMBAL_OBJ_IN_PROGRESS_SET(&(p_acc_term_inst->intf_info.interface[ii].current_int_obj_info), BCMOS_FALSE);

            intf_id++;
        }
    }
}

bcmos_errno bcmbal_interface_sub_term_list_entry_add(bcmbal_subscriber_terminal_key sub_term_key)
{
    bcmos_errno ret = BCM_ERR_OK;
    acc_term_inst *p_access_terminal_inst;
    sub_term_id_entry *current_entry;
    acc_term_interface *p_interface;

    p_access_terminal_inst = access_terminal_get();

    do
    {
        /*
         * If the specified access terminal is not active then it's interfaces are down.
         */
        if(NULL == p_access_terminal_inst)
        {
            BCM_LOG(ERROR, log_id_access_terminal,
                    "no such ACTIVE access terminal\n");
            ret = BCM_ERR_STATE;
            break;
        }

        p_interface = &p_access_terminal_inst->intf_info.interface[sub_term_key.intf_id];

        /* Check if the id is already on the list before adding it */
        TAILQ_FOREACH(current_entry,
                      &p_interface->sub_term_id_list,
                      next)
        {
            if(current_entry->sub_term_id == sub_term_key.sub_term_id)
            {
                return BCM_ERR_ALREADY;
            }
        }

        /* Get a new entry and configure it */
        current_entry = bcmos_calloc(sizeof(sub_term_id_entry));

        if (NULL == current_entry)
        {
            BCM_LOG(ERROR, log_id_access_terminal,
                    "No memory available\n");
            ret = BCM_ERR_NOMEM;
            break;
        }

        current_entry->sub_term_id = sub_term_key.sub_term_id;

        BCM_LOG(INFO, log_id_access_terminal,
                "adding sub_term id %u to interface %u\n", sub_term_key.sub_term_id, sub_term_key.intf_id);

        /* Save the entry on the list of subscriber-terminal ids on this interface */
        TAILQ_INSERT_TAIL(&p_interface->sub_term_id_list,
                          current_entry, next);

        (p_interface->num_sub_terms_on_int)++;

    } while (0);

    return ret;
}

bcmos_errno bcmbal_interface_sub_term_list_entry_remove(bcmbal_subscriber_terminal_key sub_term_key)
{
    bcmos_errno ret = BCM_ERR_NOENT;
    acc_term_inst *p_access_terminal_inst;
    acc_term_interface *p_interface;
    sub_term_id_entry *current_entry, *p_temp_entry;

    do
    {
        p_access_terminal_inst = access_terminal_get();

        /*
         * If the specified access terminal is not active then it's interfaces are down.
         */
        if(NULL == p_access_terminal_inst)
        {
            BCM_LOG(ERROR, log_id_access_terminal,
                    "no such ACTIVE access terminal\n");
            ret = BCM_ERR_STATE;
            break;
        }

        p_interface = &p_access_terminal_inst->intf_info.interface[sub_term_key.intf_id];

        /* Check if the id is on the list */
        TAILQ_FOREACH_SAFE(current_entry,
                           &p_interface->sub_term_id_list,
                           next,
                           p_temp_entry)
        {
            if(current_entry->sub_term_id == sub_term_key.sub_term_id)
            {
                /* Remove it from the list of subscriber-terminal ids on this interface */
                TAILQ_REMOVE(&p_interface->sub_term_id_list,
                             current_entry, next);

                bcmos_free(current_entry);

                (p_interface->num_sub_terms_on_int)--;

                ret = BCM_ERR_OK;
                break;

            }
        }
    } while (0);

    return ret;
}

static bcmos_errno sub_term_id_list_fill(uint32_t interface_index,
                                         bcmbal_sub_id_list_u16 *sub_term_id_list)
{
    bcmos_errno ret = BCM_ERR_OK;
    acc_term_inst *p_acc_term_inst;
    sub_term_id_entry *current_entry = NULL;
    int ii = 0;

    do
    {
        /*
         * See if the access-terminal is active
         */
        p_acc_term_inst = access_terminal_get();

        /*
         * If the specified access terminal is not active then it's interfaces are down.
         */
        if(NULL == p_acc_term_inst)
        {
            BCM_LOG(ERROR, log_id_access_terminal,
                    "no such ACTIVE access terminal\n");
            ret = BCM_ERR_NOENT;
            break;
        }

        /* Traverse the list of sub_term_ids recorded and fill in the list to be returned */
        sub_term_id_list->len = p_acc_term_inst->intf_info.interface[interface_index].num_sub_terms_on_int;
        sub_term_id_list->val = bcmos_calloc(sizeof(bcmbal_sub_id) * sub_term_id_list->len);

        if (NULL == sub_term_id_list->val)
        {
            BCM_LOG(ERROR, log_id_access_terminal,
                    "No memory available\n");
            ret = BCM_ERR_NOMEM;
            break;
        }

       TAILQ_FOREACH(current_entry,
                      &p_acc_term_inst->intf_info.interface[interface_index].sub_term_id_list,
                      next)
        {
            BCM_LOG(DEBUG, log_id_access_terminal,
                    "adding sub_term_id %u to response at array location %u\n",
                    current_entry->sub_term_id,
                    ii);
            sub_term_id_list->val[ii++] = current_entry->sub_term_id;
        }

    } while (0);

    return ret;
}

bcmos_errno bcmbal_interface_tm_get(bcmbal_interface_key key, bcmbal_tm_sched_id *id)
{
    bcmos_errno ret = BCM_ERR_OK;
    acc_term_inst *p_acc_term_inst;
    uint32_t interface_index = INVALID_INTERFACE_INDEX;

    do
    {
        /* See if the access-terminal is active */
        p_acc_term_inst = access_terminal_get();

        /* If the specified access terminal is not active then it's interfaces are down. */
        if(NULL == p_acc_term_inst)
        {
            BCM_LOG(ERROR, log_id_access_terminal,"no such ACTIVE access terminal\n");
			ret = BCM_ERR_NOT_CONNECTED;
            break;
        }

        /* If the specified access terminal is down, then it's interfaces are down. */
        if(BCMBAL_STATE_UP != p_acc_term_inst->current_acc_term_obj_info.data.admin_state)
        {
            ret = BCM_ERR_NOT_CONNECTED;
            break;
        }

        /* first get the index to the interface array from port id/type */
        interface_index = bcmbal_port_type_and_id_to_interface_index (key.intf_type, key.intf_id);
        if (interface_index >= INVALID_INTERFACE_INDEX)
        {
            BCM_LOG(ERROR, log_id_access_terminal,"INVALID port type/id (%s/%d) to interface index (%d)\n",
                interface_type_str_get(key.intf_type), key.intf_id, interface_index);
			ret = BCM_ERR_INTERNAL;
            break;
        }
        /* Retrieve the relevany default tm sched of the interface */
		if (BCMBAL_INTF_TYPE_NNI == key.intf_type)
        {
            *id = p_acc_term_inst->intf_info.interface[interface_index].current_int_obj_info.data.us_tm;
        }
        else /*BCMBAL_INTF_TYPE_PON */
        {
            *id = p_acc_term_inst->intf_info.interface[interface_index].current_int_obj_info.data.ds_tm;
        }
    }while(0);

    return ret;
}


/*****************************************************************************/
/**
 * @brief A function that returns the status of the specified interface object
 *
 * @param key       An interface instance key
 *
 * @returns bcmbal_state
 *****************************************************************************/
bcmbal_status bcmbal_interface_status_get(bcmbal_interface_key key)
{
    bcmbal_state intf_status = BCMBAL_STATUS_DOWN;
    acc_term_interface *p_acc_term_interface = bcmbal_interface_get(key);

    if(NULL == p_acc_term_interface)
    {
        BCM_LOG(ERROR, log_id_access_terminal,"no such interface\n");
    }
    else
    {
        intf_status =  p_acc_term_interface->current_int_obj_info.data.oper_status;
    }
    return intf_status;
}
/*****************************************************************************/
/**
 * @brief A function that returns the interface object
 *
 * @param key       An interface instance key
 *
 * @returns acc_term_interface  *p_acc_term_interface  a pointer to the interface object
 *****************************************************************************/
static acc_term_interface * bcmbal_interface_get(bcmbal_interface_key key)
{
    acc_term_inst *p_acc_term_inst = NULL;
    acc_term_interface *p_acc_term_interface = NULL;
    uint32_t interface_index = INVALID_INTERFACE_INDEX;

    do
    {
        /*
         * See if the access-terminal is active
         */
        p_acc_term_inst = access_terminal_get();


        /*
         * If the specified access terminal is not active then it's interfaces are down.
         */
        if(NULL == p_acc_term_inst)
        {
            BCM_LOG(ERROR, log_id_access_terminal,
                    "no such ACTIVE access terminal\n");
            break;
        }

        /*
         * Retrieve the interface
         */
        /* first get the index to the interface array from port id/type */
        interface_index = bcmbal_port_type_and_id_to_interface_index (key.intf_type, key.intf_id);
        if (interface_index >= INVALID_INTERFACE_INDEX)
        {
            BCM_LOG(ERROR, log_id_access_terminal,
                    "INVALID port type/id (%s/%d) to interface index (%d)\n",
                    interface_type_str_get(key.intf_type), key.intf_id, interface_index);
            break;
        }
        p_acc_term_interface =  &(p_acc_term_inst->intf_info.interface[interface_index]);

    }while(0);


    return p_acc_term_interface;
}

static char *interface_type_str_get(bcmbal_intf_type intf_type)
{
    return intf_type == BCMBAL_INTF_TYPE_NNI ? "NNI" :
        intf_type == BCMBAL_INTF_TYPE_PON ? "PON" : "UNKNOWN TYPE";
}
/*@}*/
