/*
<: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.

:>
*/

/*  This file is the master event handler for the EPON OAM negotiation task -
    It accepts events from the embedded software and the host interface, supported events are
    1.  Start OAM negotiaton (from host interface)
    2.  Stop OAM negotiation (from host interface)
    3.  RX Frame (from ONU via embedded firmware)
    4.  Timeout

    It dispatches these events to the OAM specific state machine. Currently we support
    OAM negotiation for BRCM, DPoE, and CTC OAM standards.
*/

#include "bcmolt_eon_private.h"
#include <bcmolt_api.h>
#include <bcmolt_model_types.h>
#include <bcmolt_msg_pack.h>
#include "oam_sets/oam_common.h"

#define EON_TASK_MSG_Q_SIZE 64

typedef enum
{
    EON_EVENT_TYPE_FRAME_RX,
    EON_EVENT_TYPE_OAM_NEG_START,
    EON_EVENT_TYPE_OAM_NEG_STOP,
    EON_EVENT_TYPE_OAM_TIMER_EXPIRE,

    EON_EVENT_TYPE_COUNT
} eon_event_type;

typedef union
{
    eon_frame_data frame_rx;
} eon_event_data;

typedef struct
{
    eon_event_type type;
    eon_link_state *link;
    eon_event_data data;
} eon_event;

typedef bcmos_errno (*eon_event_handler)(const eon_event* in_event);

static const char* _evname[EON_EVENT_TYPE_COUNT] =
{
    [EON_EVENT_TYPE_FRAME_RX] = "eon_event_type_frame_rx",
    [EON_EVENT_TYPE_OAM_NEG_START] = "eon_event_type_oam_neg_start",
    [EON_EVENT_TYPE_OAM_NEG_STOP] = "eon_event_type_oam_neg_stop",
    [EON_EVENT_TYPE_OAM_TIMER_EXPIRE] = "eon_event_type_oam_timer_expire"
};

static bcmcli_enum_val eon_oam_set_id_table[EON_OAM_SET_ID_COUNT+1] =
{
    { .name = "dpoe", .val = EON_OAM_SET_ID_DPOE },
    { .name = "brcm", .val = EON_OAM_SET_ID_BRCM },
    { .name = "ctc", .val = EON_OAM_SET_ID_CTC },
    BCMCLI_ENUM_LAST
};

eon_global_state eon_state[BCMTR_MAX_OLTS] = {};

#define HEARTBEAT_SEND_PERIOD 1
#define HEARTBEAT_SEND_OFFSET 15
#define HEARTBEAT_RECEIVE_TIMEOUT 5
#define OAM_TIMEOUT_US (HEARTBEAT_RECEIVE_TIMEOUT * 1000 * 1000)

static bcmos_bool  epon_oam_neg_running = BCMOS_FALSE;

static inline int _link_key_cmp(const eon_link_state* a, const eon_link_state* b)
{
    return memcmp(&a->link_key.link, &b->link_key.link, sizeof(a->link_key.link));
}

RB_GENERATE_INLINE(link_state_map, eon_link_state, rb_entry, _link_key_cmp);


static bcmos_errno _eon_init_task(bcmolt_devid device)
{
    bcmos_task_parm task_params =
    {
        .name         = eon_state[device].task_name,
        .priority     = TASK_PRIORITY_USER_APPL_EON,
        .core         = BCMOS_CPU_CORE_ANY, /* No CPU affinity */
        .init_handler = NULL
    };
    snprintf(eon_state[device].task_name, sizeof(eon_state[device].task_name), "user_appl_eon%u", device);
    bcmos_errno rc = bcmos_task_create(&eon_state[device].task, &task_params);

    return rc;
}


static bcmos_errno _eon_init_module(bcmolt_devid device)
{
    bcmos_module_parm module_params =
    {
        .qparm = { .name = eon_state[device].msg_queue_name, .size = EON_TASK_MSG_Q_SIZE },
        .init = NULL
    };
    snprintf(eon_state[device].msg_queue_name, sizeof(eon_state[device].msg_queue_name), "eon_msg_q%u", device);
    return bcmos_module_create(BCMOS_MODULE_ID_USER_APPL_EON + device, &eon_state[device].task, &module_params);
}

static bcmos_errno _eon_send_os_msg(bcmolt_devid device, bcmos_msg_id type, eon_task_msg_data *data)
{
    bcmos_errno rc;
    eon_task_msg *msg = bcmos_calloc(sizeof(*msg));
    if (msg == NULL)
    {
        EON_LOG(ERROR, device, "OS Message calloc failed\n");
        return BCM_ERR_NOMEM;
    }

    msg->os_msg.instance = device;
    msg->os_msg.type = type;
    msg->data = *data;
    rc = bcmos_msg_dispatch(&msg->os_msg, BCMOS_MSG_SEND_AUTO_FREE);
    if (BCM_ERR_OK != rc)
    {
        EON_LOG(ERROR, device, "OS Message send failed (%s)\n", bcmos_strerror(rc));
    }

    return rc;
}

static void _eon_destroy_link_state(eon_link_state* link_state)
{
    EON_LINK_LOG(DEBUG, &link_state->link_key, "Destroying link\n");
    bcmos_timer_destroy(&link_state->oam_timer);
    RB_REMOVE(link_state_map, &eon_state[link_state->link_key.device_id].link_state_map, link_state);
    if (NULL != link_state->tx.payload)
    {
        bcmos_free(link_state->tx.payload);
    }
    if (NULL != link_state->rx.payload)
    {
        bcmos_free(link_state->rx.payload);
    }
    if (NULL != link_state->org_spec_state)
    {
        bcmos_free(link_state->org_spec_state);
    }
    bcmos_free(link_state);
}

static eon_link_state* _eon_find_link_state(const eon_link_key* link_key)
{
    eon_link_state query_key = { .link_key.link = link_key->link };

    return RB_FIND(link_state_map, &eon_state[link_key->device_id].link_state_map, &query_key);
}

static void _eon_default_callback_fn(void *context, const eon_link_key* link_key, bcmos_errno result)
{
    eon_link_state *link_state = _eon_find_link_state(link_key);

    EON_LINK_LOG(
        INFO, link_key, "OAM negotiation completed (%s), flags %04x\n", bcmos_strerror(result), link_state->oam_state);
}

static bcmos_errno _eon_inject_frame(eon_link_key* link_key, uint16_t payload_length, uint8_t *payload_addr)
{
    bcmos_errno rc;
    bcmolt_epon_link_inject_frame inject_frame;
    bcmolt_epon_link_key epon_link_key = link_key->link;
    bcmolt_ethernet_frame_unmasked frame =
        {
            .frame_octets =
            {
                .len = payload_length,
                .val = payload_addr
            }
        };

    BCMOLT_PROXY_INIT(&inject_frame, epon_link, inject_frame, epon_link_key);
    BCMOLT_PROXY_PROP_SET(&inject_frame, epon_link, inject_frame, frame, frame);
    rc = bcmolt_proxy_send(link_key->device_id, &inject_frame.hdr);
    if (BCM_ERR_OK != rc)
    {
        EON_LINK_LOG(ERROR, link_key, "inject operation failed (%s)\n", bcmos_strerror(rc));
    }

    return rc;
}

static bcmos_errno _eon_clear_prov(eon_link_key *link_key)
{
    bcmos_errno err;
    bcmolt_epon_link_key key = link_key->link;
    bcmolt_epon_link_oam_keepalive_timer_stop stop_oper;
    bcmolt_oam_heartbeat_config hb_cfg = {};
    bcmolt_epon_link_cfg link_cfg;

    BCMOLT_OPER_INIT(&stop_oper, epon_link, oam_keepalive_timer_stop, key);
    err = bcmolt_oper_submit(link_key->device_id, &stop_oper.hdr);
    if (BCM_ERR_OK != err)
    {
        return err;
    }

    hb_cfg.transmit_frame.len = 0;
    hb_cfg.transmit_frame.val = NULL;
    hb_cfg.ignored_receive_frame_template.frame_octets.len = 0;
    hb_cfg.ignored_receive_frame_template.frame_octets.val = NULL;
    hb_cfg.ignored_receive_frame_template.mask_octets.len = 0;
    hb_cfg.ignored_receive_frame_template.mask_octets.val = NULL;
    hb_cfg.receive_timeout = 5;
    hb_cfg.maximum_receive_size = 0;
    BCMOLT_CFG_INIT(&link_cfg, epon_link, key);
    BCMOLT_CFG_PROP_SET(&link_cfg, epon_link, oam_heartbeat_config, hb_cfg);
    err = bcmolt_cfg_set(link_key->device_id, &link_cfg.hdr);

    return err;
}

static bcmos_errno _eon_set_oam_heartbeat_config(const eon_link_state *link_state)
{
    bcmos_errno rc;
    bcmolt_oam_heartbeat_config oam_heartbeat_config = {};

    oam_heartbeat_config.receive_timeout = HEARTBEAT_RECEIVE_TIMEOUT;
    oam_heartbeat_config.maximum_receive_size = link_state->max_pdu_size;

    /* The BCM68620 TX heartbeat provisioning does not include the first 15 bytes - SA, DA, EtherType or Subtype */
    oam_heartbeat_config.transmit_frame.val = &link_state->tx.payload[HEARTBEAT_SEND_OFFSET];
    oam_heartbeat_config.transmit_frame.len = link_state->tx.length - HEARTBEAT_SEND_OFFSET;

    oam_heartbeat_config.ignored_receive_frame_template.frame_octets.val = link_state->rx.payload;
    oam_heartbeat_config.ignored_receive_frame_template.frame_octets.len = link_state->rx.length;

    /* forward OAM frames with any differences to the host */
    oam_heartbeat_config.ignored_receive_frame_template.mask_octets.val = bcmos_calloc(link_state->rx.length);
    if (NULL != oam_heartbeat_config.ignored_receive_frame_template.mask_octets.val)
    {
        memset(oam_heartbeat_config.ignored_receive_frame_template.mask_octets.val, 0xFF, link_state->rx.length);
        oam_heartbeat_config.ignored_receive_frame_template.mask_octets.len = link_state->rx.length;
    }
    else
    {
        return BCM_ERR_NOMEM;
    }

    bcmolt_epon_link_cfg link_cfg;
    BCMOLT_CFG_INIT(&link_cfg, epon_link, link_state->link_key.link);
    BCMOLT_CFG_PROP_SET(&link_cfg, epon_link, oam_heartbeat_config, oam_heartbeat_config);
    rc = bcmolt_cfg_set(link_state->link_key.device_id, &link_cfg.hdr); /* call API */

    bcmos_free(oam_heartbeat_config.ignored_receive_frame_template.mask_octets.val);

    return rc;
}

static bcmos_errno _eon_start_oam_heartbeat(eon_link_state *link_state)
{
    bcmos_errno rc;

    rc = _eon_set_oam_heartbeat_config(link_state);
    if (BCM_ERR_OK == rc)
    {
        bcmolt_epon_link_key emb_link_key = link_state->link_key.link;
        bcmolt_epon_link_oam_keepalive_timer_start start_heartbeat_op;
        BCMOLT_OPER_INIT(&start_heartbeat_op, epon_link, oam_keepalive_timer_start, emb_link_key);
        BCMOLT_OPER_PROP_SET(
            &start_heartbeat_op,
            epon_link,
            oam_keepalive_timer_start,
            send_period,
            HEARTBEAT_SEND_PERIOD);
        rc = bcmolt_oper_submit(link_state->link_key.device_id, &start_heartbeat_op.hdr);
        if (BCM_ERR_OK != rc)
        {
            EON_LINK_LOG(ERROR, &link_state->link_key, "keepalive start operation submit failed (%s)\n",
                         bcmos_strerror(rc));
        }
    }
    else
    {
        EON_LINK_LOG(ERROR, &link_state->link_key, "failed to set heartbeat configuration(%s)\n", bcmos_strerror(rc));
    }

    return rc;
}

static bcmos_errno _eon_send_info_frame(eon_link_state *link_state)
{
    eon_frame_data frame_tx_req;
    bcmos_errno rc;

    rc = build_tx_info_frame(link_state, &frame_tx_req);
    if (BCM_ERR_OK == rc)
    {
        rc = _eon_inject_frame(&link_state->link_key, frame_tx_req.length, frame_tx_req.payload);
        if (BCM_ERR_OK == rc)
        {
            bcmos_timer_start(&link_state->oam_timer, OAM_TIMEOUT_US); /* start timer for rx frame */
        }
        else
        {
            EON_LINK_LOG(WARNING, &link_state->link_key, "failed to inject frame (%s)\n", bcmos_strerror(rc));
        }
        bcmos_free(frame_tx_req.payload);
    }

    return rc;
}

static bcmos_errno _eon_complete_negotiation(eon_link_state *link_state, uint8_t *rx_payload, uint16_t rx_length)
{
    bcmos_errno rc;
    eon_frame_data frame_tx_req;

    rc = build_tx_info_frame(link_state, &frame_tx_req);
    if (BCM_ERR_OK != rc)
    {
        return rc;
    }
    link_state->tx.payload = frame_tx_req.payload;
    link_state->tx.length = frame_tx_req.length;
    EON_LINK_LOG(DEBUG, &link_state->link_key, "Setting TX payload\n");

    link_state->rx.payload = bcmos_calloc(rx_length);
    if (NULL == link_state->rx.payload)
    {
        return BCM_ERR_NOMEM;
    }
    memcpy(link_state->rx.payload, rx_payload, rx_length);
    link_state->rx.length = rx_length;
    EON_LINK_LOG(DEBUG, &link_state->link_key, "Setting RX mask\n");

    if (link_state->is_heartbeat_autostart)
    {
        rc = _eon_start_oam_heartbeat(link_state);
        EON_LINK_LOG(INFO, &link_state->link_key, "start OAM heartbeat: %s\n", bcmos_strerror(rc));
    }
    link_state->callback(link_state->context, &link_state->link_key, rc);
    _eon_destroy_link_state(link_state);

    return BCM_ERR_OK;
}

static bcmos_errno _eon_event_handler_frame_rx(const eon_event* event)
{
    bcmos_errno rc;

    EON_LINK_LOG(DEBUG, &event->link->link_key, "received %u-byte frame beginning at %p\n",
                 event->data.frame_rx.length, event->data.frame_rx.payload);

    /* validates frame, updates flags */
    rc = handle_rx_info_frame(event->link, event->data.frame_rx.length, event->data.frame_rx.payload);
    switch (rc)
    {
        case BCM_ERR_OK: /* Completed Negotiation */
            rc = _eon_complete_negotiation(event->link, event->data.frame_rx.payload, event->data.frame_rx.length);
            break;
        case BCM_ERR_IN_PROGRESS:
            rc = _eon_send_info_frame(event->link);
            break;
        case BCM_ERR_PARSE:
            EON_LINK_LOG(INFO, &event->link->link_key, "received non info frame; ignoring\n");
            rc = BCM_ERR_OK; /* ...and keep running */
            break;
        default:
            break;
    }

    return rc;
}

static bcmos_errno _eon_event_handler_start(const eon_event* event)
{
    bcmos_errno rc;

    rc = _eon_clear_prov(&event->link->link_key);
    if (BCM_ERR_OK == rc)
    {
        event->link->oam_state = BCMOLT_EPON_OAM_OAM_FLAGS_LOCAL_EVALUATING;
        rc = _eon_send_info_frame(event->link);
    }
    return rc;
}

static bcmos_errno _eon_event_handler_stop(const eon_event* event)
{
    EON_LINK_LOG(INFO, &event->link->link_key, "OAM stop command received\n");
    _eon_destroy_link_state(event->link);
    return BCM_ERR_OK;
}

static bcmos_errno _eon_event_handler_oam_timer_expire(const eon_event* event)
{
    EON_LINK_LOG(WARNING, &event->link->link_key, "OAM timer expired\n");
    return BCM_ERR_TIMEOUT;
}

static const eon_event_handler event_sm[EON_EVENT_TYPE_COUNT] =
{
    [EON_EVENT_TYPE_FRAME_RX] = _eon_event_handler_frame_rx,
    [EON_EVENT_TYPE_OAM_NEG_START] = _eon_event_handler_start,
    [EON_EVENT_TYPE_OAM_NEG_STOP] = _eon_event_handler_stop,
    [EON_EVENT_TYPE_OAM_TIMER_EXPIRE] = _eon_event_handler_oam_timer_expire
};

static bcmos_errno _eon_event_handler(const eon_event* event)
{
    bcmos_errno rc = BCM_ERR_OK;

    if (event->type < EON_EVENT_TYPE_COUNT)
    {
        EON_LINK_LOG(DEBUG, &event->link->link_key, "event %s\n", _evname[event->type]);
        rc = event_sm[event->type](event);
    }
    else
    {
        EON_LINK_LOG(ERROR, &event->link->link_key, "unknown event %d\n", event->type);
    }

    return rc;
}

static void _eon_event_dispatch(const eon_event* event_in)
{
    bcmos_errno rc;

    rc = _eon_event_handler(event_in);
    if (rc != BCM_ERR_OK)
    {
        event_in->link->callback(event_in->link->context, &event_in->link->link_key, rc);
        _eon_destroy_link_state(event_in->link);
    }
}

static bcmos_timer_rc _eon_oam_timer_expire(bcmos_timer* timer, long pUser)
{
    eon_event event = { .type = EON_EVENT_TYPE_OAM_TIMER_EXPIRE, .link = (eon_link_state *)pUser };

    _eon_event_dispatch(&event);

    return BCMOS_TIMER_OK;
}

static bcmos_errno _eon_create_link_state(
    eon_link_state **state,
    eon_link_key* link_key,
    eon_oam_set_id oam_set,
    bcmolt_eon_result_cb cb,
    void *context,
    bcmos_bool is_heartbeat_autostart)
{
    bcmos_errno rc;
    eon_link_state *link_state;

    link_state = _eon_find_link_state(link_key);
    if (link_state != NULL)
    {
        EON_LINK_LOG(ERROR, link_key, "OAM negotiation is already in progress\n");
        return BCM_ERR_ALREADY;
    }

    link_state = bcmos_calloc(sizeof(*link_state));
    if (link_state == NULL)
    {
        EON_LINK_LOG(ERROR, link_key, "Failed to allocate state record\n");
        return BCM_ERR_NOMEM;
    }

    bcmolt_epon_ni_key ni_key = { .epon_ni = link_key->link.epon_ni };
    bcmolt_epon_ni_cfg ni_cfg;

    BCMOLT_CFG_INIT(&ni_cfg, epon_ni, ni_key);
    BCMOLT_CFG_PROP_GET(&ni_cfg, epon_ni, mac_address);
    rc = bcmolt_cfg_get(link_key->device_id, &ni_cfg.hdr);
    if (BCM_ERR_OK == rc)
    {
        link_state->epon_ni_mac_addr = ni_cfg.data.mac_address;
    }
    else
    {
        EON_LINK_LOG(ERROR, link_key, "Failed to retrieve EPON NI MAC address: %s\n", bcmos_strerror(rc));
        bcmos_free(link_state);
        return rc;
    }

    bcmos_timer_parm timer_spec =
    {
        .owner   = BCMOS_MODULE_ID_USER_APPL_EON + link_key->device_id,
        .handler = _eon_oam_timer_expire,
        .data    = (long)link_state
    };
    rc = bcmos_timer_create(&link_state->oam_timer, &timer_spec);
    if (BCM_ERR_OK != rc)
    {
        EON_LINK_LOG(ERROR, link_key, "Failed to create timer: %s\n", bcmos_strerror(rc));
        bcmos_free(link_state);
        return rc;
    }

    link_state->link_key = *link_key;
    link_state->callback = cb ? cb : _eon_default_callback_fn;
    link_state->context = context;
    link_state->is_heartbeat_autostart = is_heartbeat_autostart;
    link_state->oam_set = oam_set;
    link_state->max_pdu_size = 1536;

    RB_INSERT(link_state_map, &eon_state[link_key->device_id].link_state_map, link_state);

    *state = link_state;

    return BCM_ERR_OK;
}

static void _eon_task_process_rx(bcmolt_devid device_id, const bcmolt_proxy_rx *rx)
{
    eon_event event  = { .type = EON_EVENT_TYPE_FRAME_RX };

    const bcmolt_epon_link_key* epon_link_key = (const bcmolt_epon_link_key*)(rx + 1);
    eon_link_key link_key = { .device_id = device_id, .link = *epon_link_key };
    eon_link_state *link_state = _eon_find_link_state(&link_key);

    if (link_state != NULL)
    {
        EON_LINK_LOG(DEBUG, &link_key, "found existing link\n");
        const bcmolt_u8_list_u32 frame = ((const bcmolt_epon_link_frame_captured*)rx)->data.frame;
        event.link = link_state;
        event.data.frame_rx.payload = frame.val;
        event.data.frame_rx.length  = frame.len;
        _eon_event_dispatch(&event);
    }
    else
    {
        EON_LINK_LOG(DEBUG, &link_key, "rx on unknown link\n");
    }
}

static void _eon_handle_proxy_rx(bcmos_module_id module_id, bcmos_msg *os_msg)
{
    eon_task_msg *msg = (eon_task_msg*)os_msg;

    _eon_task_process_rx(os_msg->instance, msg->data.proxy_rx.rx);

    bcmolt_msg_free(&msg->data.proxy_rx.rx->hdr); /* free cloned indication */
    bcmos_free(os_msg);
}

static void _eon_handle_start(bcmos_module_id module_id, bcmos_msg *os_msg)
{
    eon_task_msg *msg = (eon_task_msg*)os_msg;
    eon_link_key link_key = { .device_id = os_msg->instance, .link = msg->data.start.link_key };
    eon_event event = { .type = EON_EVENT_TYPE_OAM_NEG_START };

    if (BCM_ERR_OK == _eon_create_link_state(
        &event.link,
        &link_key,
        msg->data.start.oam_set,
        msg->data.start.cb,
        msg->data.start.context,
        msg->data.start.is_heartbeat_autostart))
    {
        _eon_event_dispatch(&event);
    }

    bcmos_free(os_msg);
}

static void _eon_handle_stop(bcmos_module_id module_id, bcmos_msg *os_msg)
{
    eon_task_msg *msg = (eon_task_msg*)os_msg;
    eon_link_key link_key = { .device_id = os_msg->instance, .link = msg->data.stop.link_key };
    eon_event event = { .type = EON_EVENT_TYPE_OAM_NEG_STOP, .link = _eon_find_link_state(&link_key) };

    if (NULL != event.link)
    {
        _eon_event_dispatch(&event);
    }

    bcmos_free(os_msg);
}

static bcmos_errno _eon_cmd_start(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    bcmos_errno rc;
    eon_task_msg_data msg_data;

    msg_data.start.link_key.epon_ni = (bcmolt_epon_ni)bcmcli_find_named_parm(session, "epon_ni")->value.unumber;
    msg_data.start.link_key.mac_address = bcmcli_find_named_parm(session, "mac_address")->value.mac;
    msg_data.start.oam_set = (eon_oam_set_id)bcmcli_find_named_parm(session, "oam_set")->value.enum_val;
    msg_data.start.cb = NULL;
    msg_data.start.context = NULL;
    msg_data.start.is_heartbeat_autostart = BCMOS_TRUE;

    rc = _eon_send_os_msg(current_device, BCMOS_MSG_ID_EON_START, &msg_data);

    return rc;
}

static bcmos_errno _eon_cmd_stop(bcmcli_session *session,
                                 const bcmcli_cmd_parm parm[],
                                 uint16_t n_parms)
{
    bcmos_errno rc;
    eon_task_msg_data msg_data;

    msg_data.stop.link_key.epon_ni = (bcmolt_epon_ni)bcmcli_find_named_parm(session, "epon_ni")->value.unumber;
    msg_data.stop.link_key.mac_address = bcmcli_find_named_parm(session, "mac_address")->value.mac;

    rc = _eon_send_os_msg(current_device, BCMOS_MSG_ID_EON_STOP, &msg_data);

    return rc;
}


static bcmos_errno _eon_cmd_show(
    bcmcli_session        *session,
    const bcmcli_cmd_parm  parm[],
    uint16_t               n_parms)
{
    eon_link_state*   link_state;
    bcmos_bool          no_links = BCMOS_TRUE;

    RB_FOREACH(link_state, link_state_map, &eon_state[current_device].link_state_map)
    {
        no_links = BCMOS_FALSE;
        bcmcli_session_print(session,
                             "-->  "LINK_KEY_FMT_STR"  OAM set %u   state %04x\n",
                             LINK_KEY_DATA(&link_state->link_key),
                             link_state->oam_set,
                             link_state->oam_state);
    }
    if (no_links)
    {
        bcmcli_session_print(session, "no links\n");
    }

    return BCM_ERR_OK;
}


void bcmolt_user_appl_eon_cli_init(bcmcli_entry *top_dir)
{
    static const char *dir_name = "eon";

    if (bcmcli_dir_find(top_dir, dir_name))
    {
        return;
    }

    bcmcli_entry *dir = bcmcli_dir_add(top_dir,
                                       dir_name,
                                       "EPON OAM negotiation commands",
                                       BCMCLI_ACCESS_ADMIN, NULL);
    BUG_ON(dir == NULL);

    BCMCLI_MAKE_CMD_NOPARM(dir,
                           "show",
                           "Show current EON configuration and state",
                           _eon_cmd_show);

    BCMCLI_MAKE_CMD(dir,
                    "start_oam_negotiation",
                    "Start OAM negotiation for an EPON link",
                    _eon_cmd_start,
                    BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE),
                    BCMCLI_MAKE_PARM("mac_address", "MAC address", BCMCLI_PARM_MAC, BCMCLI_PARM_FLAG_NONE),
                    BCMCLI_MAKE_PARM_ENUM("oam_set", "OAM set", eon_oam_set_id_table, BCMCLI_PARM_FLAG_NONE));


    BCMCLI_MAKE_CMD(dir,
                    "stop_oam_negotiation",
                    "Stop in progress OAM negotiation for an EPON link",
                    _eon_cmd_stop,
                    BCMCLI_MAKE_PARM("epon_ni", "EPON NI", BCMCLI_PARM_NUMBER, BCMCLI_PARM_FLAG_NONE),
                    BCMCLI_MAKE_PARM("mac_address", "MAC address", BCMCLI_PARM_MAC, BCMCLI_PARM_FLAG_NONE) );
}


void bcmolt_user_appl_eon_init(void)
{
    bcmos_errno rc;

    if (epon_oam_neg_running)
    {
        return;
    }

    for (bcmolt_devid device = 0; device < BCMTR_MAX_OLTS; device++)
    {
        rc = _eon_init_task(device);
        BUG_ON(rc != BCM_ERR_OK);

        rc = _eon_init_module(device);
        BUG_ON(rc != BCM_ERR_OK);

        char log_name[MAX_DEV_LOG_ID_NAME];
        snprintf(log_name, sizeof(log_name), "user_appl_eon%u", device);
        eon_state[device].log_id = bcm_dev_log_id_register(log_name, DEV_LOG_LEVEL_INFO, DEV_LOG_ID_TYPE_BOTH);

        bcmos_msg_register(
            BCMOS_MSG_ID_EON_START,
            device,
            BCMOS_MODULE_ID_USER_APPL_EON + device,
            _eon_handle_start);
        bcmos_msg_register(
            BCMOS_MSG_ID_EON_STOP,
            device,
            BCMOS_MODULE_ID_USER_APPL_EON + device,
            _eon_handle_stop);
        bcmos_msg_register(
            BCMOS_MSG_ID_EON_PROXY_RX,
            device,
            BCMOS_MODULE_ID_USER_APPL_EON + device,
            _eon_handle_proxy_rx);

        // initialize the state map
        RB_INIT(&eon_state[device].link_state_map);
    }

    epon_oam_neg_running = BCMOS_TRUE;
}

// public indication handler interface -- called in transport layer context
bcmos_errno bcmolt_user_appl_eon_process_rx(bcmolt_devid device_id, bcmolt_proxy_rx *rx)
{
     bcmos_errno rc;
     eon_task_msg_data msg_data = {};

     /* Not running --> silently ignore  */
     if (!epon_oam_neg_running)
     {
         return BCM_ERR_OK;
     }

     /* Not our message --> silenty ignore */
     if ( (BCMOLT_OBJ_ID_EPON_LINK != rx->hdr.obj_type) ||
          (BCMOLT_EPON_LINK_PROXY_RX_ID_FRAME_CAPTURED != rx->hdr.subgroup) )
     {
         return BCM_ERR_OK;
     }

     /* This is something this application does care about - so clone the message into
        newly-allocated memory so we can handle it after the original message has been freed */
     rc = bcmolt_msg_clone((bcmolt_msg**)&msg_data.proxy_rx.rx, &rx->hdr);
     if (rc != BCM_ERR_OK)
     {
         EON_LOG(ERROR, device_id, "Message clone failed: %s\n", bcmos_strerror(rc));
         return rc;
     }

     rc = _eon_send_os_msg(device_id, BCMOS_MSG_ID_EON_PROXY_RX, &msg_data);
     if (rc != BCM_ERR_OK)
     {
         bcmolt_msg_free(&msg_data.proxy_rx.rx->hdr);
     }
     return rc;
}

