/*
<:copyright-BRCM:2016:DUAL/GPL:standard

   Broadcom Proprietary and Confidential.(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.

:>
*/

#include <bcmolt_host_api.h>
#include "bcmolt_user_appl_ps.h"
#include "bcmolt_user_appl_ps_internal.h"

static bcmos_errno ps_handle_ni_los(
    const bcmolt_ps_global_cfg *global_cfg,
    const bcmolt_ps_pon *pon,
    const bcmolt_xgpon_ni_los *ind)
{
    if (ind->data.status == BCMOLT_STATUS_OFF)
    {
        PS_INFO("<%d:%d> LoS alarm cleared\n", pon->device_id, pon->pon_id);
        return BCM_ERR_OK;
    }

    PS_INFO("<%d:%d> LoS alarm raised\n", pon->device_id, pon->pon_id);

    if (global_cfg->switch_condition == BCMOLT_PS_SWITCH_CONDITION_MANUAL)
    {
        /* don't react to the switch if we're in manual switch mode */
        return BCM_ERR_OK;
    }
    else
    {
        return bcmolt_ps_switch_perform(pon);
    }
}

static bcmos_errno ps_handle_ni_state_changed(
    const bcmolt_ps_pon *partner,
    const bcmolt_xgpon_ni_state_change_completed *ind)
{
    bcmolt_xgpon_ni_key key = { partner->pon_id };
    bcmolt_xgpon_ni_set_pon_state oper;

    BCMOLT_OPER_INIT(&oper, xgpon_ni, set_pon_state, key);

    if (ind->data.previous_state == BCMOLT_PON_STATE_INACTIVE &&
        ind->data.new_state == BCMOLT_PON_STATE_ACTIVE_WORKING)
    {
        PS_INFO("%s: activating PON <%d:%d>\n", __FUNCTION__, partner->device_id, key.pon_ni);
        BCMOLT_OPER_PROP_SET(&oper, xgpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_ACTIVE_STANDBY);
    }
    else if (ind->data.previous_state == BCMOLT_PON_STATE_ACTIVE_WORKING &&
        ind->data.new_state == BCMOLT_PON_STATE_INACTIVE)
    {
        PS_INFO("%s: deactivating PON <%d:%d>\n", __FUNCTION__, partner->device_id, key.pon_ni);
        BCMOLT_OPER_PROP_SET(&oper, xgpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_INACTIVE);
    }
    else
    {
        /* only change the standby PON's state if we're pre-provisioning the working PON
          (the switchover is handled separately) */
        return BCM_ERR_OK;
    }

    return bcmolt_oper_submit(partner->device_id, &oper.hdr);
}

static bcmos_errno ps_handle_ni_traffic_resume(
    const bcmolt_ps_pon *pon,
    const bcmolt_xgpon_ni_protection_switching_traffic_resume *ind)
{
    uint32_t after_us  = bcmos_timestamp();
    uint32_t before_us = ps_get_last_switch_start_time_us();
    uint32_t time_taken_us = (after_us > before_us) ? after_us - before_us : before_us - after_us;
    const char *traffic_resume_result_str = NULL;

    switch (ind->data.result)
    {
    case BCMOLT_TRAFFIC_RESUME_RESULT_SUCCESS:
        traffic_resume_result_str = "success";
        break;
    case BCMOLT_TRAFFIC_RESUME_RESULT_FAILURE:
        traffic_resume_result_str = "failure";
        break;
    case BCMOLT_TRAFFIC_RESUME_RESULT_SUSPECTED_LOS:
        traffic_resume_result_str = "suspected_los";
        break;
    default:
        break;
    }

    PS_INFO(
        "<%d:%d> Traffic resume %s. Time since start of switch: %d ms.\n",
        pon->device_id,
        pon->pon_id,
        traffic_resume_result_str,
        time_taken_us / 1000);

    return BCM_ERR_OK;
}

static bcmos_errno ps_handle_ni_onus_ranged(
    const bcmolt_ps_pon *partner,
    const bcmolt_xgpon_ni_protection_switching_onus_ranged *ind)
{
    uint32_t i;
    bcmos_errno last_err = BCM_ERR_OK;

    /* apply all of the new ONU EQDs to the standby PON */
    for (i = 0; i < ind->data.onus.len; i++)
    {
        bcmolt_xgpon_onu_key key = { partner->pon_id, ind->data.onus.val[i].onu_id };
        bcmolt_xgpon_onu_cfg cfg;
        bcmos_errno err;

        PS_INFO(
            "%s: updating EQD <%d:%d> ONU %d -> %d\n",
            __FUNCTION__,
            partner->device_id,
            key.pon_ni,
            key.onu_id,
            ind->data.onus.val[i].eqd);

        BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
        BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, ranging_time, ind->data.onus.val[i].eqd);
        err = bcmolt_cfg_set(partner->device_id, &cfg.hdr);
        if (err != BCM_ERR_OK)
        {
            PS_ERR("EQD update failed: %s\n", bcmos_strerror(err));
            last_err = err;
        }
    }

    return last_err;
}

static bcmos_errno ps_handle_onu_ranging_completed(
    const bcmolt_ps_pon *partner,
    const bcmolt_xgpon_onu_ranging_completed *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;

    /* only react to success indications */
    if (ind->data.status != BCMOLT_RESULT_SUCCESS)
    {
        return BCM_ERR_OK;
    }

    PS_INFO(
        "%s: updating EQD <%d:%d> ONU %d -> %d\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id,
        ind->data.eqd);

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, ranging_time, ind->data.eqd);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_key_exchange_completed(
    const bcmolt_ps_pon *pon,
    const bcmolt_ps_pon *partner,
    const bcmolt_xgpon_onu_key_exchange_completed *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;

    PS_INFO("%s: updating AES key <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, current_encryption_key, ind->data.new_key);
    return bcmolt_cfg_set(pon->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_activation_completed(
    const bcmolt_ps_pon *pon,
    const bcmolt_ps_pon *partner,
    const bcmolt_xgpon_onu_onu_activation_completed *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;
    bcmolt_xgpon_onu_set_onu_state oper;
    bcmos_errno err;

    /* only react to success indications */
    if (ind->data.status != BCMOLT_RESULT_SUCCESS)
    {
        return BCM_ERR_OK;
    }

    PS_INFO(
        "%s: provisioning registration ID / keys for newly-activated ONU <%d:%d> ONU %d\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id);

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, registration_id, ind->data.registration_id);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, registration_encryption_keys, ind->data.registration_encryption_keys);
    err = bcmolt_cfg_set(partner->device_id, &cfg.hdr);
    if (err != BCM_ERR_OK)
    {
        return err;
    }

    PS_INFO("%s: activating <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);

    BCMOLT_OPER_INIT(&oper, xgpon_onu, set_onu_state, key);
    BCMOLT_OPER_PROP_SET(&oper, xgpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_ACTIVE);
    return bcmolt_oper_submit(partner->device_id, &oper.hdr);
}

static bcmos_errno ps_handle_onu_deactivation_completed(
    const bcmolt_ps_pon *partner,
    const bcmolt_xgpon_onu_onu_deactivation_completed *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_set_onu_state oper;

    /* Note: we react to this indication whether or not the deactivation was successful.  Failure indicates that the
     * ONU didn't respond to the deactivation, but we still remove the ONU from OLT hardware so it must be mirrored. */

    PS_INFO("%s: deactivating <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);

    BCMOLT_OPER_INIT(&oper, xgpon_onu, set_onu_state, key);
    BCMOLT_OPER_PROP_SET(&oper, xgpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_INACTIVE);
    return bcmolt_oper_submit(partner->device_id, &oper.hdr);
}

static bcmos_errno ps_handle_onu_enable_completed(
    const bcmolt_ps_pon *partner,
    const bcmolt_xgpon_onu_onu_enable_completed *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_set_onu_state oper;

    /* don't try to mirror broadcast enable/disable */
    if (key.onu_id == BCMOLT_XGPON_ONU_ID_INVALID)
    {
        return BCM_ERR_OK;
    }

    PS_INFO("%s: enabling <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);

    BCMOLT_OPER_INIT(&oper, xgpon_onu, set_onu_state, key);
    BCMOLT_OPER_PROP_SET(&oper, xgpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_ENABLE);
    return bcmolt_oper_submit(partner->device_id, &oper.hdr);
}

static bcmos_errno ps_handle_onu_disable_completed(
    const bcmolt_ps_pon *partner,
    const bcmolt_xgpon_onu_onu_disable_completed *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_set_onu_state oper;

    /* don't try to mirror broadcast enable/disable */
    if (key.onu_id == BCMOLT_XGPON_ONU_ID_INVALID)
    {
        return BCM_ERR_OK;
    }

    PS_INFO("%s: disabling <%d:%d> ONU %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.onu_id);

    BCMOLT_OPER_INIT(&oper, xgpon_onu, set_onu_state, key);
    BCMOLT_OPER_PROP_SET(&oper, xgpon_onu, set_onu_state, onu_state, BCMOLT_ONU_OPERATION_DISABLE);
    return bcmolt_oper_submit(partner->device_id, &oper.hdr);
}

static void ps_alarm_state_init(bcmolt_xgpon_onu_alarm_state *alarm_state)
{
    alarm_state->losi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->lobi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->lopci = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->lopci_mic_error = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->looci = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->tiwi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->dowi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->sufi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->sfi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->sdi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->dfi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->dgi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->pqsi = BCMOLT_STATUS_NO_CHANGE;
}

static bcmos_errno ps_handle_onu_alarm(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_onu_alarm *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;
    bcmolt_xgpon_onu_alarm_state alarm_state;

    ps_alarm_state_init(&alarm_state);
    alarm_state.losi = ind->data.onu_alarm.losi;
    alarm_state.lobi = ind->data.onu_alarm.lobi;
    alarm_state.lopci = ind->data.onu_alarm.lopci_miss;
    alarm_state.lopci_mic_error = ind->data.onu_alarm.lopci_mic_error;

    PS_INFO(
        "%s: updating ONU alarms <%d:%d> ONU %d\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id);

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_dowi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_dowi *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;
    bcmolt_xgpon_onu_alarm_state alarm_state;

    PS_INFO(
        "%s: updating DOWi <%d:%d> ONU %d -> %d (EQD %d)\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id,
        ind->data.alarm_status,
        ind->data.new_eqd);

    ps_alarm_state_init(&alarm_state);
    alarm_state.dowi = ind->data.alarm_status;

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state);

    if (ind->data.alarm_status == BCMOLT_STATUS_ON)
    {
        BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, ranging_time, ind->data.new_eqd);
    }

    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_sfi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_sfi *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;
    bcmolt_xgpon_onu_alarm_state alarm_state;

    PS_INFO(
        "%s: updating SFI <%d:%d> ONU %d -> %d\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id,
        ind->data.alarm_status);

    ps_alarm_state_init(&alarm_state);
    alarm_state.sfi = ind->data.alarm_status;

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_sdi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_sdi *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;
    bcmolt_xgpon_onu_alarm_state alarm_state;

    PS_INFO(
        "%s: updating SDi <%d:%d> ONU %d -> %d\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id,
        ind->data.alarm_status);

    ps_alarm_state_init(&alarm_state);
    alarm_state.sdi = ind->data.alarm_status;

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_dfi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_dfi *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;
    bcmolt_xgpon_onu_alarm_state alarm_state;

    PS_INFO(
        "%s: updating DFi <%d:%d> ONU %d -> %d\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id,
        ind->data.alarm_status);

    ps_alarm_state_init(&alarm_state);
    alarm_state.dfi = ind->data.alarm_status;

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_sufi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_sufi *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;
    bcmolt_xgpon_onu_alarm_state alarm_state;

    PS_INFO(
        "%s: updating SUFi <%d:%d> ONU %d -> %d\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id,
        ind->data.alarm_status);

    ps_alarm_state_init(&alarm_state);
    alarm_state.sufi = ind->data.alarm_status;

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_tiwi(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_tiwi *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;
    bcmolt_xgpon_onu_alarm_state alarm_state;

    PS_INFO(
        "%s: updating TIWi <%d:%d> ONU %d -> %d\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id,
        ind->data.alarm_status);

    ps_alarm_state_init(&alarm_state);
    alarm_state.tiwi = ind->data.alarm_status;

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_looci(const bcmolt_ps_pon *partner, const bcmolt_xgpon_onu_looci *ind)
{
    bcmolt_xgpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_xgpon_onu_cfg cfg;
    bcmolt_xgpon_onu_alarm_state alarm_state;

    PS_INFO(
        "%s: updating LOOCi <%d:%d> ONU %d -> %d\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id,
        ind->data.alarm_status);

    ps_alarm_state_init(&alarm_state);
    alarm_state.looci = ind->data.alarm_status;

    BCMOLT_CFG_INIT(&cfg, xgpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, xgpon_onu, alarm_state, alarm_state);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_alloc_id_configuration_completed(
    const bcmolt_ps_pon *partner,
    const bcmolt_xgpon_alloc_configuration_completed *ind)
{
    bcmolt_xgpon_alloc_key key = { partner->pon_id, ind->key.alloc_id };
    bcmolt_xgpon_alloc_set_state oper;

    BCMOLT_OPER_INIT(&oper, xgpon_alloc, set_state, key);

    if (ind->data.new_state == BCMOLT_ALLOC_STATE_ACTIVE)
    {
        /* only react to success indications */
        if (ind->data.status != BCMOLT_RESULT_SUCCESS)
        {
            return BCM_ERR_OK;
        }

        PS_INFO("%s: activating <%d:%d> alloc %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.alloc_id);
        BCMOLT_OPER_PROP_SET(&oper, xgpon_alloc, set_state, state, BCMOLT_ALLOC_OPERATION_ACTIVATE);
    }
    else if (ind->data.new_state == BCMOLT_ALLOC_STATE_INACTIVE)
    {
        PS_INFO("%s: deactivating <%d:%d> alloc %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.alloc_id);
        BCMOLT_OPER_PROP_SET(&oper, xgpon_alloc, set_state, state, BCMOLT_ALLOC_OPERATION_DEACTIVATE);
    }
    else /* ind->data.new_state is something else (e.g. unprovisioned, if the alloc was cleared) */
    {
        return BCM_ERR_OK;
    }

    return bcmolt_oper_submit(partner->device_id, &oper.hdr);
}

bcmos_errno ps_process_ind_xgpon(const bcmolt_ps_pon *pon, const bcmolt_auto *ind)
{
    bcmos_errno err;
    bcmolt_ps_pon_state state;
    bcmolt_ps_pon partner;
    bcmolt_ps_global_cfg global_cfg;

    err = bcmolt_ps_global_cfg_get(&global_cfg);
    if (err != BCM_ERR_OK)
    {
        return err;
    }

    if (global_cfg.mirror_mode != BCMOLT_PS_MIRROR_MODE_AUTO &&
        ind->hdr.subgroup != BCMOLT_XGPON_NI_AUTO_ID_LOS)
    {
        /* only handle most indications while in mirror mode 'auto', but perform a switchover on LoS in any case  */
        return BCM_ERR_OK;
    }

    err = bcmolt_ps_pon_state_get(pon, &state, &partner);
    if (err != BCM_ERR_OK)
    {
        return err;
    }

    if (state != BCMOLT_PS_PON_STATE_WORKING)
    {
        return BCM_ERR_OK; /* ignore indications from PONs that aren't protected working */
    }

    switch (ind->hdr.obj_type)
    {
    case BCMOLT_OBJ_ID_XGPON_NI:
        switch (ind->hdr.subgroup)
        {
        case BCMOLT_XGPON_NI_AUTO_ID_LOS:
            return ps_handle_ni_los(&global_cfg, pon, ((const bcmolt_xgpon_ni_los *)ind));
        case BCMOLT_XGPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED:
            return ps_handle_ni_state_changed(&partner, ((const bcmolt_xgpon_ni_state_change_completed *)ind));
        case BCMOLT_XGPON_NI_AUTO_ID_PROTECTION_SWITCHING_TRAFFIC_RESUME:
            return ps_handle_ni_traffic_resume(pon, ((const bcmolt_xgpon_ni_protection_switching_traffic_resume *)ind));
        case BCMOLT_XGPON_NI_AUTO_ID_PROTECTION_SWITCHING_ONUS_RANGED:
            return ps_handle_ni_onus_ranged(&partner, ((const bcmolt_xgpon_ni_protection_switching_onus_ranged *)ind));
        default:
            return BCM_ERR_OK; /* silently ignore all other NI indications */
        }

    case BCMOLT_OBJ_ID_XGPON_ONU:
        switch (ind->hdr.subgroup)
        {
        case BCMOLT_XGPON_ONU_AUTO_ID_RANGING_COMPLETED:
            return ps_handle_onu_ranging_completed(&partner, ((const bcmolt_xgpon_onu_ranging_completed *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_KEY_EXCHANGE_COMPLETED:
            return ps_handle_onu_key_exchange_completed(
                pon,
                &partner,
                ((const bcmolt_xgpon_onu_key_exchange_completed *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_ONU_ACTIVATION_COMPLETED:
            return ps_handle_onu_activation_completed(
                pon,
                &partner,
                ((const bcmolt_xgpon_onu_onu_activation_completed *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_ONU_DEACTIVATION_COMPLETED:
            return ps_handle_onu_deactivation_completed(
                &partner,
                ((const bcmolt_xgpon_onu_onu_deactivation_completed *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_ONU_ENABLE_COMPLETED:
            return ps_handle_onu_enable_completed(&partner, ((const bcmolt_xgpon_onu_onu_enable_completed *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_ONU_DISABLE_COMPLETED:
            return ps_handle_onu_disable_completed(&partner, ((const bcmolt_xgpon_onu_onu_disable_completed *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_ONU_ALARM:
            return ps_handle_onu_alarm(&partner, ((const bcmolt_xgpon_onu_onu_alarm *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_DOWI:
            return ps_handle_onu_dowi(&partner, ((const bcmolt_xgpon_onu_dowi *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_SFI:
            return ps_handle_onu_sfi(&partner, ((const bcmolt_xgpon_onu_sfi *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_SDI:
            return ps_handle_onu_sdi(&partner, ((const bcmolt_xgpon_onu_sdi *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_DFI:
            return ps_handle_onu_dfi(&partner, ((const bcmolt_xgpon_onu_dfi *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_SUFI:
            return ps_handle_onu_sufi(&partner, ((const bcmolt_xgpon_onu_sufi *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_TIWI:
            return ps_handle_onu_tiwi(&partner, ((const bcmolt_xgpon_onu_tiwi *)ind));
        case BCMOLT_XGPON_ONU_AUTO_ID_LOOCI:
            return ps_handle_onu_looci(&partner, ((const bcmolt_xgpon_onu_looci *)ind));
        default:
            return BCM_ERR_OK; /* silently ignore all other ONU indications */
        }

    case BCMOLT_OBJ_ID_XGPON_ALLOC:
        switch (ind->hdr.subgroup)
        {
        case BCMOLT_XGPON_ALLOC_AUTO_ID_CONFIGURATION_COMPLETED:
            return ps_handle_alloc_id_configuration_completed(
                &partner,
                ((const bcmolt_xgpon_alloc_configuration_completed *)ind));
        default:
            return BCM_ERR_OK; /* silently ignore all other alloc indications */
        }

    default:
        return BCM_ERR_NOT_SUPPORTED; /* someone else needs to handle this indication */
    }
}

bcmos_errno ps_move_to_standby_xgpon(const bcmolt_ps_pon *pon)
{
    bcmolt_xgpon_ni_set_pon_state set_pon_state;
    bcmolt_xgpon_ni_key key = { (bcmolt_xgpon_ni)pon->pon_id };

    BCMOLT_OPER_INIT(&set_pon_state, xgpon_ni, set_pon_state, key);
    BCMOLT_OPER_PROP_SET(&set_pon_state, xgpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_ACTIVE_STANDBY);
    return bcmolt_oper_submit(pon->device_id, &set_pon_state.hdr);
}

bcmos_errno ps_move_to_working_xgpon(const bcmolt_ps_pon *pon)
{
    bcmolt_xgpon_ni_set_pon_state set_pon_state;
    bcmolt_xgpon_ni_key key = { (bcmolt_xgpon_ni)pon->pon_id };

    BCMOLT_OPER_INIT(&set_pon_state, xgpon_ni, set_pon_state, key);
    BCMOLT_OPER_PROP_SET(&set_pon_state, xgpon_ni, set_pon_state, pon_state, BCMOLT_PON_OPERATION_ACTIVE_WORKING);
    return bcmolt_oper_submit(pon->device_id, &set_pon_state.hdr);
}
