/*
<: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_gpon_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_gpon_ni_state_change_completed *ind)
{
    bcmolt_gpon_ni_key key = { partner->pon_id };
    bcmolt_gpon_ni_set_pon_state oper;

    BCMOLT_OPER_INIT(&oper, gpon_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, gpon_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, gpon_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_gpon_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_gpon_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_gpon_onu_key key = { partner->pon_id, ind->data.onus.val[i].onu_id };
        bcmolt_gpon_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, gpon_onu, key);
        BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_ranging_completed *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_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, gpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_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 *partner,
    const bcmolt_gpon_onu_key_exchange_completed *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_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, gpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, aes_encryption_key, ind->data.new_key);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_password_authentication_completed(
    const bcmolt_ps_pon *partner,
    const bcmolt_gpon_onu_password_authentication_completed *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;

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

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

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

static bcmos_errno ps_handle_onu_activation_completed(
    const bcmolt_ps_pon *partner,
    const bcmolt_gpon_onu_onu_activation_completed *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_set_onu_state oper;

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

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

    BCMOLT_OPER_INIT(&oper, gpon_onu, set_onu_state, key);
    BCMOLT_OPER_PROP_SET(&oper, gpon_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_gpon_onu_onu_deactivation_completed *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_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, gpon_onu, set_onu_state, key);
    BCMOLT_OPER_PROP_SET(&oper, gpon_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_gpon_onu_onu_enable_completed *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_set_onu_state oper;

    /* don't try to mirror broadcast enable/disable */
    if (key.onu_id == BCMOLT_GPON_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, gpon_onu, set_onu_state, key);
    BCMOLT_OPER_PROP_SET(&oper, gpon_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_gpon_onu_onu_disable_completed *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_set_onu_state oper;

    /* don't try to mirror broadcast enable/disable */
    if (key.onu_id == BCMOLT_GPON_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, gpon_onu, set_onu_state, key);
    BCMOLT_OPER_PROP_SET(&oper, gpon_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_gpon_onu_alarm_state *alarm_state)
{
    alarm_state->losi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->lofi = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->loami = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->dgi = 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->loai = BCMOLT_STATUS_NO_CHANGE;
    alarm_state->loki = BCMOLT_STATUS_NO_CHANGE;
}

static bcmos_errno ps_handle_onu_alarm(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_onu_alarm *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;
    bcmolt_gpon_onu_alarm_state alarm_state;

    ps_alarm_state_init(&alarm_state);
    alarm_state.losi = ind->data.onu_alarm.losi;
    alarm_state.lofi = ind->data.onu_alarm.lofi;
    alarm_state.loami = ind->data.onu_alarm.loami;
    
    PS_INFO(
        "%s: updating ONU alarms <%d:%d> ONU %d -> %d/%d/%d\n",
        __FUNCTION__,
        partner->device_id,
        key.pon_ni,
        key.onu_id,
        alarm_state.losi,
        alarm_state.lofi,
        alarm_state.loami);

    BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_dowi *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;
    bcmolt_gpon_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, gpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);

    if (ind->data.alarm_status == BCMOLT_STATUS_ON)
    {
        BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_sfi *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;
    bcmolt_gpon_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, gpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_sdi *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;
    bcmolt_gpon_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, gpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_dfi *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;
    bcmolt_gpon_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, gpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_sufi *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;
    bcmolt_gpon_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, gpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_loai(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_loai *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;
    bcmolt_gpon_onu_alarm_state alarm_state;

    PS_INFO(
        "%s: updating LOAi <%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.loai = ind->data.alarm_status;

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

static bcmos_errno ps_handle_onu_dgi(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_dgi *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;
    bcmolt_gpon_onu_alarm_state alarm_state;

    PS_INFO(
        "%s: updating DGi <%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.dgi = ind->data.alarm_status;

    BCMOLT_CFG_INIT(&cfg, gpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_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_gpon_onu_tiwi *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;
    bcmolt_gpon_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, gpon_onu, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_onu, alarm_state, alarm_state);
    return bcmolt_cfg_set(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_onu_loki(const bcmolt_ps_pon *partner, const bcmolt_gpon_onu_loki *ind)
{
    bcmolt_gpon_onu_key key = { partner->pon_id, ind->key.onu_id };
    bcmolt_gpon_onu_cfg cfg;
    bcmolt_gpon_onu_alarm_state alarm_state;

    PS_INFO(
        "%s: updating LOKi <%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.loki = ind->data.alarm_status;

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

static bcmos_errno ps_handle_onu_omci_port_configuration_completed(
    const bcmolt_ps_pon *partner,
    const bcmolt_gpon_onu_omci_port_id_configuration_completed *ind)
{
    bcmolt_gpon_gem_port_key key = { partner->pon_id, ind->data.gem_port };
    bcmolt_gpon_gem_port_set_state oper;

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

    if (ind->data.operation == BCMOLT_OMCI_PORT_ID_OPERATION_CONFIGURE)
    {
        /* don't react to unsuccessful activations */
        if (ind->data.status != BCMOLT_RESULT_SUCCESS)
        {
            return BCM_ERR_OK;
        }

        PS_INFO("%s: activating <%d:%d> GEM port ID %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.gem_port_id);
        BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_ACTIVATE);
    }
    else
    {
        PS_INFO(
            "%s: deactivating <%d:%d> GEM port ID %d\n",
            __FUNCTION__,
            partner->device_id,
            key.pon_ni,
            key.gem_port_id);
        BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_DEACTIVATE);
    }

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

static bcmos_errno ps_handle_mac_table_new_mac(
    const bcmolt_ps_global_cfg *global_cfg,
    const bcmolt_ps_pon *partner,
    const bcmolt_gpon_iwf_mac_table_new_mac *ind)
{
    bcmolt_gpon_iwf_mac_table_key key = { partner->pon_id, ind->key.mac_address, ind->key.vlan };
    bcmolt_gpon_iwf_mac_table_cfg cfg;

    if (!global_cfg->mirror_mac_entries)
    {
        return BCM_ERR_OK; /* we are not configured to mirror MAC entries */
    }

    BCMOLT_CFG_INIT(&cfg, gpon_iwf_mac_table, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, flow_id, ind->data.flow_id);

    if (global_cfg->static_mac_entries)
    {
        BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, stat, BCMOS_TRUE);
    }
    else
    {
        BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, stat, BCMOS_FALSE);
    }

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

static bcmos_errno ps_handle_mac_table_mac_aged(
    const bcmolt_ps_global_cfg *global_cfg,
    const bcmolt_ps_pon *partner,
    const bcmolt_gpon_iwf_mac_table_mac_aged *ind)
{
    bcmolt_gpon_iwf_mac_table_key key = { partner->pon_id, ind->key.mac_address, ind->key.vlan };
    bcmolt_gpon_iwf_mac_table_cfg cfg;

    if (!global_cfg->mirror_mac_entries)
    {
        return BCM_ERR_OK; /* we are not configured to mirror MAC entries */
    }

    BCMOLT_CFG_INIT(&cfg, gpon_iwf_mac_table, key);
    return bcmolt_cfg_clear(partner->device_id, &cfg.hdr);
}

static bcmos_errno ps_handle_mac_table_mac_move(
    const bcmolt_ps_global_cfg *global_cfg,
    const bcmolt_ps_pon *partner,
    const bcmolt_gpon_iwf_mac_table_mac_move *ind)
{
    bcmolt_gpon_iwf_mac_table_key key = { partner->pon_id, ind->key.mac_address, ind->key.vlan };
    bcmolt_gpon_iwf_mac_table_cfg cfg;

    if (!global_cfg->mirror_mac_entries)
    {
        return BCM_ERR_OK; /* we are not configured to mirror MAC entries */
    }

    BCMOLT_CFG_INIT(&cfg, gpon_iwf_mac_table, key);
    BCMOLT_CFG_PROP_SET(&cfg, gpon_iwf_mac_table, flow_id, ind->data.new_flow_id);
    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_gpon_alloc_configuration_completed *ind)
{
    bcmolt_gpon_alloc_key key = { partner->pon_id, ind->key.alloc_id };
    bcmolt_gpon_alloc_set_state oper;

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

    if (ind->data.new_state == BCMOLT_ALLOC_STATE_ACTIVE)
    {
        /* don't react to unsuccessful activations */
        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, gpon_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, gpon_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);
}

static bcmos_errno ps_handle_gem_port_configuration_completed(
    const bcmolt_ps_pon *partner,
    const bcmolt_gpon_gem_port_configuration_completed *ind)
{
    bcmolt_gpon_gem_port_key key = { partner->pon_id, ind->key.gem_port_id };
    bcmolt_gpon_gem_port_set_state oper;

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

    if (ind->data.new_state == BCMOLT_GPON_GEM_PORT_STATE_ACTIVE)
    {
        /* don't react to unsuccessful activations */
        if (ind->data.status != BCMOLT_RESULT_SUCCESS)
        {
            return BCM_ERR_OK;
        }

        PS_INFO("%s: activating <%d:%d> GEM port ID %d\n", __FUNCTION__, partner->device_id, key.pon_ni, key.gem_port_id);
        BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_ACTIVATE);
    }
    else if (ind->data.new_state == BCMOLT_GPON_GEM_PORT_STATE_INACTIVE)
    {
        PS_INFO(
            "%s: deactivating <%d:%d> GEM port ID %d\n",
            __FUNCTION__,
            partner->device_id,
            key.pon_ni,
            key.gem_port_id);
        BCMOLT_OPER_PROP_SET(&oper, gpon_gem_port, set_state, state, BCMOLT_GEM_PORT_OPERATION_DEACTIVATE);
    }
    else /* ind->data.new_state is something else (e.g. unprovisioned, if the GEM port was cleared) */
    {
        return BCM_ERR_OK;
    }

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

bcmos_errno ps_process_ind_gpon(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_GPON_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_GPON_NI:
        switch (ind->hdr.subgroup)
        {
        case BCMOLT_GPON_NI_AUTO_ID_LOS:
            return ps_handle_ni_los(&global_cfg, pon, ((const bcmolt_gpon_ni_los *)ind));
        case BCMOLT_GPON_NI_AUTO_ID_STATE_CHANGE_COMPLETED:
            return ps_handle_ni_state_changed(&partner, ((const bcmolt_gpon_ni_state_change_completed *)ind));
        case BCMOLT_GPON_NI_AUTO_ID_PROTECTION_SWITCHING_TRAFFIC_RESUME:
            return ps_handle_ni_traffic_resume(pon, ((const bcmolt_gpon_ni_protection_switching_traffic_resume *)ind));
        case BCMOLT_GPON_NI_AUTO_ID_PROTECTION_SWITCHING_ONUS_RANGED:
            return ps_handle_ni_onus_ranged(&partner, ((const bcmolt_gpon_ni_protection_switching_onus_ranged *)ind));
        default:
            return BCM_ERR_OK; /* silently ignore all other NI indications */
        }

    case BCMOLT_OBJ_ID_GPON_ONU:
        switch (ind->hdr.subgroup)
        {
        case BCMOLT_GPON_ONU_AUTO_ID_RANGING_COMPLETED:
            return ps_handle_onu_ranging_completed(&partner, ((const bcmolt_gpon_onu_ranging_completed *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_KEY_EXCHANGE_COMPLETED:
            return ps_handle_onu_key_exchange_completed(
                &partner,
                ((const bcmolt_gpon_onu_key_exchange_completed *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_PASSWORD_AUTHENTICATION_COMPLETED:
            return ps_handle_onu_password_authentication_completed(
                &partner,
                ((const bcmolt_gpon_onu_password_authentication_completed *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_ONU_ACTIVATION_COMPLETED:
            return ps_handle_onu_activation_completed(
                &partner,
                ((const bcmolt_gpon_onu_onu_activation_completed *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_ONU_DEACTIVATION_COMPLETED:
            return ps_handle_onu_deactivation_completed(
                &partner,
                ((const bcmolt_gpon_onu_onu_deactivation_completed *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_ONU_ENABLE_COMPLETED:
            return ps_handle_onu_enable_completed(&partner, ((const bcmolt_gpon_onu_onu_enable_completed *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_ONU_DISABLE_COMPLETED:
            return ps_handle_onu_disable_completed(&partner, ((const bcmolt_gpon_onu_onu_disable_completed *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_ONU_ALARM:
            return ps_handle_onu_alarm(&partner, ((const bcmolt_gpon_onu_onu_alarm *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_DOWI:
            return ps_handle_onu_dowi(&partner, ((const bcmolt_gpon_onu_dowi *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_SFI:
            return ps_handle_onu_sfi(&partner, ((const bcmolt_gpon_onu_sfi *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_SDI:
            return ps_handle_onu_sdi(&partner, ((const bcmolt_gpon_onu_sdi *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_DFI:
            return ps_handle_onu_dfi(&partner, ((const bcmolt_gpon_onu_dfi *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_SUFI:
            return ps_handle_onu_sufi(&partner, ((const bcmolt_gpon_onu_sufi *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_LOAI:
            return ps_handle_onu_loai(&partner, ((const bcmolt_gpon_onu_loai *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_DGI:
            return ps_handle_onu_dgi(&partner, ((const bcmolt_gpon_onu_dgi *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_TIWI:
            return ps_handle_onu_tiwi(&partner, ((const bcmolt_gpon_onu_tiwi *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_LOKI:
            return ps_handle_onu_loki(&partner, ((const bcmolt_gpon_onu_loki *)ind));
        case BCMOLT_GPON_ONU_AUTO_ID_OMCI_PORT_ID_CONFIGURATION_COMPLETED:
            return ps_handle_onu_omci_port_configuration_completed(
                &partner,
                ((const bcmolt_gpon_onu_omci_port_id_configuration_completed *)ind));
        default:
            return BCM_ERR_OK; /* silently ignore all other ONU indications */
        }

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

    case BCMOLT_OBJ_ID_GPON_GEM_PORT:
        switch (ind->hdr.subgroup)
        {
        case BCMOLT_GPON_GEM_PORT_AUTO_ID_CONFIGURATION_COMPLETED:
            return ps_handle_gem_port_configuration_completed(
                &partner,
                ((const bcmolt_gpon_gem_port_configuration_completed *)ind));
        default:
            return BCM_ERR_OK; /* silently ignore all other GEM port indications */
        }

    case BCMOLT_OBJ_ID_GPON_IWF_MAC_TABLE:
        switch (ind->hdr.subgroup)
        {
        case BCMOLT_GPON_IWF_MAC_TABLE_AUTO_CFG_ID_NEW_MAC:
            return ps_handle_mac_table_new_mac(
                &global_cfg,
                &partner,
                (const bcmolt_gpon_iwf_mac_table_new_mac *)ind);
        case BCMOLT_GPON_IWF_MAC_TABLE_AUTO_CFG_ID_MAC_AGED:
            return ps_handle_mac_table_mac_aged(
                &global_cfg,
                &partner,
                (const bcmolt_gpon_iwf_mac_table_mac_aged *)ind);
        case BCMOLT_GPON_IWF_MAC_TABLE_AUTO_CFG_ID_MAC_MOVE:
            return ps_handle_mac_table_mac_move(
                &global_cfg, 
                &partner,
                (const bcmolt_gpon_iwf_mac_table_mac_move *)ind);
        default:
            return BCM_ERR_OK; /* silently ignore all other mac table indications */
        }

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

bcmos_errno ps_move_to_standby_gpon(const bcmolt_ps_pon *pon)
{
    bcmolt_gpon_ni_set_pon_state set_pon_state;
    bcmolt_gpon_ni_key key = { (bcmolt_gpon_ni)pon->pon_id };

    BCMOLT_OPER_INIT(&set_pon_state, gpon_ni, set_pon_state, key);
    BCMOLT_OPER_PROP_SET(&set_pon_state, gpon_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_gpon(const bcmolt_ps_pon *pon)
{
    bcmolt_gpon_ni_set_pon_state set_pon_state;
    bcmolt_gpon_ni_key key = { (bcmolt_gpon_ni)pon->pon_id };

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