/*
<: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_gpon_utils.h"
#include <bcmolt_dev_selector.h>

static bcmcli_entry *gpon_utils_cli_dir;
static bcmcli_entry *gpon_utils_cli_top_dir;
static bcmos_bool gpon_utils_is_registered;

static bcmos_errno bcmolt_user_appl_gpon_utils_create(bcmcli_entry *top_dir);

#define MAX_GEM_PORTS_FOR_SEND     64
#define MAX_ONUS_FOR_SEND          64
#define MAX_PACKET_SIZE            2048

typedef enum
{
    GENERATED_PACKET_PATTERN_BYTE_CYCLE,
    GENERATED_PACKET_PATTERN_WORD_CYCLE,
    GENERATED_PACKET_PATTERN_CONST
} generated_packet_pattern;

typedef enum
{
    PON_MODE_GPON,
    PON_MODE_XGPON,
    PON_MODE_INVALID
} pon_mode;

static uint8_t saved_packet[MAX_PACKET_SIZE];
static bcmolt_packet_type saved_packet_type;
static bcmos_bool saved_packet_calc_crc;
static uint16_t saved_packet_len = 0;

static void gpon_utils_cli_dir_cli_destroy(void)
{
    if (gpon_utils_cli_dir)
    {
        bcmcli_token_destroy(gpon_utils_cli_dir);
        gpon_utils_cli_dir = NULL;
    }
}

/* Current device change indication */
static void bcmolt_user_appl_gpon_utils_device_change_ind(bcmcli_session *session, bcmolt_devid dev)
{
    bcmolt_system_mode system_mode;
    bcmos_errno err = bcmolt_system_mode_get(dev, &system_mode);

    if (err != BCM_ERR_OK)
    {
        bcmcli_session_print(session, "Error device Id\n");
        return;
    }

    if (system_mode == BCMOLT_SYSTEM_MODE_GPON__16_X ||
        system_mode == BCMOLT_SYSTEM_MODE_GPON__8_X ||
        system_mode == BCMOLT_SYSTEM_MODE_GPON__4_X ||
        system_mode == BCMOLT_SYSTEM_MODE_XGPON_1__8_X ||
        system_mode == BCMOLT_SYSTEM_MODE_XGPON_1__4_X ||
        system_mode == BCMOLT_SYSTEM_MODE_XGS__2_X_10_G ||
        system_mode == BCMOLT_SYSTEM_MODE_NGPON2__2_X_10_G)
    {
        bcmcli_session_print(session, "Building gpon_utils CLI for device %d\n", dev);

        err = bcmolt_user_appl_gpon_utils_create(gpon_utils_cli_top_dir);
        if (err)
        {
            bcmcli_session_print(session, "Error building gpon_utils CLI\n");
        }
    }
    else
    {
        gpon_utils_cli_dir_cli_destroy();
    }
}

static inline pon_mode pon_mode_get(bcmolt_pon_ni pon_id)
{
    bcmolt_system_mode system_mode;
    bcmos_errno err = bcmolt_system_mode_get(current_device, &system_mode);
    if (err != BCM_ERR_OK)
    {
        return PON_MODE_INVALID;
    }

    if (system_mode == BCMOLT_SYSTEM_MODE_GPON_8_XGPON_4_X_COEXISTENCE)
    {
        /* special handling for the 8x GPON / 4x XGPON co-existence mode */
        return pon_id < 8 ? PON_MODE_XGPON : PON_MODE_GPON;
    }
    else if (bcmolt_obj_tag_valid_for_system_mode(system_mode, BCMOLT_OBJ_TAG_GPON))
    {
        return PON_MODE_GPON;
    }
    else if (bcmolt_obj_tag_valid_for_system_mode(system_mode, BCMOLT_OBJ_TAG_XGPON))
    {
        return PON_MODE_XGPON;
    }
    else
    {
        return PON_MODE_INVALID;
    }
}

static bcmos_errno build_packet(bcmcli_session *session, bcmolt_packet_type type)
{
    uint16_t i;
    bcmos_bool calc_crc = (bcmos_bool)bcmcli_find_named_parm(session, "calc_crc")->value.unumber;
    uint16_t packet_size = (uint16_t)bcmcli_find_named_parm(session, "packet_size")->value.unumber;
    generated_packet_pattern pattern = 
        (generated_packet_pattern)bcmcli_find_named_parm(session, "pattern")->value.unumber;
    uint8_t const_value = (uint8_t)bcmcli_find_named_parm(session, "const_value")->value.unumber;
    uint16_t data_offset;
    
    /* save packet type / size / CRC flag */
    saved_packet_type = type;
    saved_packet_len = packet_size;
    saved_packet_calc_crc = calc_crc;

    if (type == BCMOLT_PACKET_TYPE_CPU)
    {
        bcmos_mac_address eth_da = bcmcli_find_named_parm(session, "eth_da")->value.mac;
        bcmos_mac_address eth_sa = bcmcli_find_named_parm(session, "eth_sa")->value.mac;

        /* copy destination MAC */
        memcpy(saved_packet, &eth_da, 6);

        /* copy source MAC */
        memcpy(&saved_packet[6], &eth_sa, 6);

        /* write EtherType of 0000 */
        memset(&saved_packet[12], 0, 2);

        /* data starts after EtherType */
        data_offset = 14;
    }
    else
    {
        /* fill the entire packet */
        data_offset = 0;
    }

    /* fill the rest of the buffer using the specified data pattern */
    switch (pattern)
    {
    case GENERATED_PACKET_PATTERN_BYTE_CYCLE:
        const_value = 0;
        for (i = data_offset; i < packet_size; i++)
        {
            saved_packet[i] = const_value++;
        }
        break;
    case GENERATED_PACKET_PATTERN_WORD_CYCLE:
        /* first 4 bytes = 00000000, next 4 = 11111111, next 4 = 22222222, etc */
        const_value = 0;
        for (i = data_offset; i < packet_size; i += 4)
        {
            uint16_t j;
            for (j = i; j < i + 4 && j < packet_size; j++)
            {
                saved_packet[j] = const_value;
            }
            const_value = (const_value == 0xFF) ? 0 : const_value + 0x11;
        }
        break;
    case GENERATED_PACKET_PATTERN_CONST:
        for (i = data_offset; i < packet_size; i++)
        {
            saved_packet[i] = const_value;
        }
        break;
    default:
        bcmcli_session_print(session, "[Error] Invalid pattern: %u\n", pattern);
        return BCM_ERR_INTERNAL;
    }

    return BCM_ERR_OK;
}

static bcmos_errno build_cpu_packet_cb(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    bcmos_errno err = build_packet(session, BCMOLT_PACKET_TYPE_CPU);
    if (err == BCM_ERR_OK)
    {
        bcmcli_session_print(session, "CPU packet buffer saved successfully\n");
    }
    else
    {
        bcmcli_session_print(session, "[Error] saving CPU packet buffer: %s\n", bcmos_strerror(err));
    }
    return err;
}

static bcmos_errno build_omci_packet_cb(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    bcmos_errno err = build_packet(session, BCMOLT_PACKET_TYPE_OMCI);
    if (err == BCM_ERR_OK)
    {
        bcmcli_session_print(session, "OMCI packet buffer saved successfully\n");
    }
    else
    {
        bcmcli_session_print(session, "[Error] saving OMCI packet buffer: %s\n", bcmos_strerror(err));
    }
    return err;
}

static bcmos_errno send_packet_to_gpon_gem_list(bcmcli_session *session, uint16_t gem_count, bcmolt_gpon_gem_id *gems)
{
    uint16_t count = 1;
    uint16_t i;
    uint16_t gem_idx;
    bcmos_errno err;
    bcmcli_cmd_parm *parm;
    bcmolt_devid device = (bcmolt_devid)bcmcli_find_named_parm(session, "device")->value.unumber;
    bcmolt_pon_ni pon_ni = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;
    bcmolt_gpon_ni_key pon_ni_key = { .pon_ni = pon_ni };
    bcmolt_gpon_gem_id_list_u8_max_16 gem_port_list;
    bcmolt_gpon_ni_cpu_packets proxy;
    bcmolt_u8_list_u32_max_2048 buffer = { .len = saved_packet_len, .val = saved_packet };

    if (saved_packet_len == 0)
    {
        bcmcli_session_print(session, "[Error] you must build/save a packet before you can send it\n");
        return BCM_ERR_PARM;
    }

    parm = bcmcli_find_named_parm(session, "count");
    if (parm != NULL)
    {
        count = (uint16_t)parm->value.unumber;
    }

    bcmcli_session_print(
        session,
        "Sending %u proxy packet%s to %u GEM port%s...\n",
        count,
        count == 1 ? "" : "s",
        gem_count,
        gem_count == 1 ? "" : "s");

    /* build the proxy API message, except the GEM port list */
    BCMOLT_PROXY_INIT(&proxy, gpon_ni, cpu_packets, pon_ni_key);
    BCMOLT_PROXY_PROP_SET(&proxy, gpon_ni, cpu_packets, packet_type, saved_packet_type);
    BCMOLT_PROXY_PROP_SET(&proxy, gpon_ni, cpu_packets, calc_crc, saved_packet_calc_crc);
    BCMOLT_PROXY_PROP_SET(&proxy, gpon_ni, cpu_packets, buffer, buffer);

    /* call the proxy API <count> times */
    for (i = 0; i < count; i++)
    {
        /* we may need to split this up into multiple API calls (only 16 GEM ports are allowed per proxy API) */
        for (gem_idx = 0; gem_idx < gem_count; gem_idx += 16)
        {
            gem_port_list.len = MIN(16, gem_count - gem_idx);
            gem_port_list.val = &gems[gem_idx];
            BCMOLT_PROXY_PROP_SET(&proxy, gpon_ni, cpu_packets, gem_port_list, gem_port_list);

            err = bcmolt_proxy_send(device, &proxy.hdr);
            if (err != BCM_ERR_OK)
            {
                bcmcli_session_print(
                    session,
                    "[Error] proxy send: packet index %u GEM index %u: %s\n",
                    i,
                    gem_idx,
                    bcmos_strerror(err));
                return err;
            }
        }
    }

    bcmcli_session_print(session, "%u proxy packet%s sent successfully!\n", count, count == 1 ? "" : "s");
    return BCM_ERR_OK;
}

static bcmos_errno send_packet_to_xgpon_gem_list(bcmcli_session *session, uint16_t gem_count, bcmolt_xgpon_gem_id *gems)
{
    uint16_t count = 1;
    uint16_t i;
    uint16_t gem_idx;
    bcmos_errno err;
    bcmcli_cmd_parm *parm;
    bcmolt_devid device = (bcmolt_devid)bcmcli_find_named_parm(session, "device")->value.unumber;
    bcmolt_pon_ni pon_ni = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;
    bcmolt_xgpon_ni_key pon_ni_key = { .pon_ni = pon_ni };
    bcmolt_xgpon_gem_id_list_u8_max_16 gem_port_list;
    bcmolt_xgpon_ni_cpu_packets proxy;
    bcmolt_u8_list_u32_max_2048 buffer = { .len = saved_packet_len, .val = saved_packet };

    if (saved_packet_len == 0)
    {
        bcmcli_session_print(session, "[Error] you must build/save a packet before you can send it\n");
        return BCM_ERR_PARM;
    }

    parm = bcmcli_find_named_parm(session, "count");
    if (parm != NULL)
    {
        count = (uint16_t)parm->value.unumber;
    }

    bcmcli_session_print(
        session,
        "Sending %u proxy packet%s to %u GEM port%s...\n",
        count,
        count == 1 ? "" : "s",
        gem_count,
        gem_count == 1 ? "" : "s");

    /* build the proxy API message, except the GEM port list */
    BCMOLT_PROXY_INIT(&proxy, xgpon_ni, cpu_packets, pon_ni_key);
    BCMOLT_PROXY_PROP_SET(&proxy, xgpon_ni, cpu_packets, packet_type, saved_packet_type);
    BCMOLT_PROXY_PROP_SET(&proxy, xgpon_ni, cpu_packets, calc_crc, saved_packet_calc_crc);
    BCMOLT_PROXY_PROP_SET(&proxy, xgpon_ni, cpu_packets, buffer, buffer);

    /* call the proxy API <count> times */
    for (i = 0; i < count; i++)
    {
        /* we may need to split this up into multiple API calls (only 16 GEM ports are allowed per proxy API) */
        for (gem_idx = 0; gem_idx < gem_count; gem_idx += 16)
        {
            gem_port_list.len = MIN(16, gem_count - gem_idx);
            gem_port_list.val = &gems[gem_idx];
            BCMOLT_PROXY_PROP_SET(&proxy, xgpon_ni, cpu_packets, gem_port_list, gem_port_list);

            err = bcmolt_proxy_send(device, &proxy.hdr);
            if (err != BCM_ERR_OK)
            {
                bcmcli_session_print(
                    session,
                    "[Error] proxy send: packet index %u GEM index %u: %s\n",
                    i,
                    gem_idx,
                    bcmos_strerror(err));
                return err;
            }
        }
    }

    bcmcli_session_print(session, "%u proxy packet%s sent successfully!\n", count, count == 1 ? "" : "s");
    return BCM_ERR_OK;
}

static bcmos_errno send_to_gem_cb(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    bcmcli_cmd_parm *gem_parm = bcmcli_find_named_parm(session, "gem");
    bcmolt_pon_ni pon_id = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;
    uint16_t i;
    pon_mode mode = pon_mode_get(pon_id);

    if (mode == PON_MODE_GPON)
    {
        static bcmolt_gpon_gem_id gem_id_buf[MAX_GEM_PORTS_FOR_SEND];
        for (i = 0; i < gem_parm->array_size; i++)
        {
            gem_id_buf[i] = (bcmolt_gpon_gem_id)gem_parm->values[i].unumber;
        }
        return send_packet_to_gpon_gem_list(session, (uint16_t)gem_parm->array_size, gem_id_buf);
    } 
    else if (mode == PON_MODE_XGPON)
    {
        static bcmolt_xgpon_gem_id gem_id_buf[MAX_GEM_PORTS_FOR_SEND];
        for (i = 0; i < gem_parm->array_size; i++)
        {
            gem_id_buf[i] = (bcmolt_xgpon_gem_id)gem_parm->values[i].unumber;
        }
        return send_packet_to_xgpon_gem_list(session, (uint16_t)gem_parm->array_size, gem_id_buf);
    }
    else
    {
        bcmcli_session_print(session, "[Error] Invalid system mode\n");
        return BCM_ERR_INTERNAL;
    }
}

static bcmos_errno send_packet_to_gpon_onu_list(bcmcli_session *session, uint16_t onu_count, bcmolt_gpon_onu_id *onus)
{
    uint16_t count = 1;
    uint16_t i;
    uint16_t onu_idx;
    bcmos_errno err;
    bcmcli_cmd_parm *parm;
    bcmolt_devid device = (bcmolt_devid)bcmcli_find_named_parm(session, "device")->value.unumber;
    bcmolt_pon_ni pon_ni = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;

    if (saved_packet_len == 0)
    {
        bcmcli_session_print(session, "[Error] you must build/save a packet before you can send it\n");
        return BCM_ERR_PARM;
    }

    parm = bcmcli_find_named_parm(session, "count");
    if (parm != NULL)
    {
        count = (uint16_t)parm->value.unumber;
    }

    bcmcli_session_print(
        session,
        "Sending %u proxy packet%s to %u ONU%s...\n",
        count,
        count == 1 ? "" : "s",
        onu_count,
        onu_count == 1 ? "" : "s");

    /* call the proxy API (potentially several times) for each ONU */
    for (onu_idx = 0; onu_idx < onu_count; onu_idx++)
    {
        bcmolt_gpon_onu_key onu_key = { .pon_ni = pon_ni, .onu_id = onus[onu_idx] };
        bcmolt_u8_list_u32_max_2048 buffer = { .val = saved_packet };
        bcmolt_gpon_onu_cpu_packets proxy;
        uint16_t packets_per_proxy;

        /* build the proxy API message, except the buffer/number of packets */
        BCMOLT_PROXY_INIT(&proxy, gpon_onu, cpu_packets, onu_key);
        BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, packet_type, saved_packet_type);
        BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, calc_crc, saved_packet_calc_crc);
        BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, packet_size, saved_packet_len);

        /* calculate the number of packets we can fit per invocation of the proxy API */
        packets_per_proxy = MIN(count, 2048 / saved_packet_len);
        BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, number_of_packets, packets_per_proxy);

        /* prepare the buffer data with several copies of the same packet in a row */
        for (i = 1; i < packets_per_proxy; i++)
        {
            memcpy(&saved_packet[i * saved_packet_len], saved_packet, saved_packet_len); 
        }

        /* call the proxy API enough times to send the requested number of packets */
        for (i = 0; i < count; i += packets_per_proxy)
        {
            uint16_t number_of_packets = MIN(packets_per_proxy, count - i);
            BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, number_of_packets, number_of_packets);

            buffer.len = number_of_packets * saved_packet_len;
            BCMOLT_PROXY_PROP_SET(&proxy, gpon_onu, cpu_packets, buffer, buffer);

            err = bcmolt_proxy_send(device, &proxy.hdr);
            if (err != BCM_ERR_OK)
            {
                bcmcli_session_print(
                    session,
                    "[Error] proxy send: ONU %u packet index %u: %s\n",
                    onus[onu_idx],
                    i,
                    bcmos_strerror(err));
                return err;
            }
        }
    }

    bcmcli_session_print(session, "%u proxy packet%s sent successfully!\n", count, count == 1 ? "" : "s");
    return BCM_ERR_OK;
}

static bcmos_errno send_packet_to_xgpon_onu_list(bcmcli_session *session, uint16_t onu_count, bcmolt_xgpon_onu_id *onus)
{
    uint16_t count = 1;
    uint16_t i;
    uint16_t onu_idx;
    bcmos_errno err;
    bcmcli_cmd_parm *parm;
    bcmolt_devid device = (bcmolt_devid)bcmcli_find_named_parm(session, "device")->value.unumber;
    bcmolt_pon_ni pon_ni = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;

    if (saved_packet_len == 0)
    {
        bcmcli_session_print(session, "[Error] you must build/save a packet before you can send it\n");
        return BCM_ERR_PARM;
    }

    parm = bcmcli_find_named_parm(session, "count");
    if (parm != NULL)
    {
        count = (uint16_t)parm->value.unumber;
    }

    bcmcli_session_print(
        session,
        "Sending %u proxy packet%s to %u ONU%s...\n",
        count,
        count == 1 ? "" : "s",
        onu_count,
        onu_count == 1 ? "" : "s");

    /* call the proxy API (potentially several times) for each ONU */
    for (onu_idx = 0; onu_idx < onu_count; onu_idx++)
    {
        bcmolt_xgpon_onu_key onu_key = { .pon_ni = pon_ni, .onu_id = onus[onu_idx] };
        bcmolt_u8_list_u32_max_2048 buffer = { .val = saved_packet };
        bcmolt_xgpon_onu_cpu_packets proxy;
        uint16_t packets_per_proxy;

        /* build the proxy API message, except the buffer/number of packets */
        BCMOLT_PROXY_INIT(&proxy, xgpon_onu, cpu_packets, onu_key);
        BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, packet_type, saved_packet_type);
        BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, calc_crc, saved_packet_calc_crc);
        BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, packet_size, saved_packet_len);

        /* calculate the number of packets we can fit per invocation of the proxy API */
        packets_per_proxy = MIN(count, 2048 / saved_packet_len);
        BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, number_of_packets, packets_per_proxy);

        /* prepare the buffer data with several copies of the same packet in a row */
        for (i = 1; i < packets_per_proxy; i++)
        {
            memcpy(&saved_packet[i * saved_packet_len], saved_packet, saved_packet_len); 
        }

        /* call the proxy API enough times to send the requested number of packets */
        for (i = 0; i < count; i += packets_per_proxy)
        {
            uint16_t number_of_packets = MIN(packets_per_proxy, count - i);
            BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, number_of_packets, number_of_packets);

            buffer.len = number_of_packets * saved_packet_len;
            BCMOLT_PROXY_PROP_SET(&proxy, xgpon_onu, cpu_packets, buffer, buffer);

            err = bcmolt_proxy_send(device, &proxy.hdr);
            if (err != BCM_ERR_OK)
            {
                bcmcli_session_print(
                    session,
                    "[Error] proxy send: ONU %u packet index %u: %s\n",
                    onus[onu_idx],
                    i,
                    bcmos_strerror(err));
                return err;
            }
        }
    }

    bcmcli_session_print(session, "%u proxy packet%s sent successfully!\n", count, count == 1 ? "" : "s");
    return BCM_ERR_OK;
}

static bcmos_errno send_to_onu_cb(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    bcmcli_cmd_parm *onu_parm = bcmcli_find_named_parm(session, "onu");
    bcmolt_pon_ni pon_id = (bcmolt_pon_ni)bcmcli_find_named_parm(session, "pon_ni")->value.unumber;
    uint16_t i;
    pon_mode mode = pon_mode_get(pon_id);

    if (mode == PON_MODE_GPON)
    {
        static bcmolt_gpon_onu_id onu_id_buf[MAX_ONUS_FOR_SEND];
        for (i = 0; i < onu_parm->array_size; i++)
        {
            onu_id_buf[i] = (bcmolt_gpon_onu_id)onu_parm->values[i].unumber;
        }
        return send_packet_to_gpon_onu_list(session, (uint16_t)onu_parm->array_size, onu_id_buf);
    } 
    else if (mode == PON_MODE_XGPON)
    {
        static bcmolt_xgpon_onu_id onu_id_buf[MAX_ONUS_FOR_SEND];
        for (i = 0; i < onu_parm->array_size; i++)
        {
            onu_id_buf[i] = (bcmolt_xgpon_onu_id)onu_parm->values[i].unumber;
        }
        return send_packet_to_xgpon_onu_list(session, (uint16_t)onu_parm->array_size, onu_id_buf);
    }
    else
    {
        bcmcli_session_print(session, "[Error] Invalid system mode\n");
        return BCM_ERR_STATE;
    }
}

static void dump_saved_mac(bcmcli_session *session, uint16_t offset)
{
    uint16_t i;
    for (i = 0; i < 6; i++)
    {
        if (i != 0)
        {
            bcmcli_session_print(session, ":");
        }
        bcmcli_session_print(session, "%02X", saved_packet[offset + i]);
    }
}

static bcmos_errno dump_packet_cb(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    uint16_t i;
    uint16_t data_offset;

    if (saved_packet_len == 0)
    {
        bcmcli_session_print(session, "No packet has been built yet\n");
        return BCM_ERR_OK;
    }

    bcmcli_session_print(session, "Saved packet parameters:\n");
    bcmcli_session_print(session, "    Type: %s\n", saved_packet_type == BCMOLT_PACKET_TYPE_CPU ? "CPU" : "OMCI");
    bcmcli_session_print(session, "    Length: %u\n", saved_packet_len);
    bcmcli_session_print(session, "    Auto-calculate CRC: %s\n", saved_packet_calc_crc ? "yes" : "no");

    if (saved_packet_type == BCMOLT_PACKET_TYPE_CPU)
    {
        bcmcli_session_print(session, "    Ethernet DA: ");
        dump_saved_mac(session, 0);
        bcmcli_session_print(session, "\n");

        bcmcli_session_print(session, "    Ethernet SA: ");
        dump_saved_mac(session, 6);
        bcmcli_session_print(session, "\n");

        bcmcli_session_print(session, "    EtherType: 0x%02X%02X\n", saved_packet[12], saved_packet[13]);
        data_offset = 14;
    }
    else
    {
        data_offset = 0;
    }

    bcmcli_session_print(session, "Data bytes (starting at offset %u):", data_offset);
    for (i = data_offset; i < saved_packet_len; i++)
    {
        if ((i - data_offset) % 16 == 0)
        {
            bcmcli_session_print(session, "\n    ");
        }
        else
        {
            bcmcli_session_print(session, " ");
        }
        bcmcli_session_print(session, "%02X", saved_packet[i]);
    }
    bcmcli_session_print(session, "\n");

    return BCM_ERR_OK;
}

bcmos_errno bcmolt_user_appl_gpon_utils_init(bcmcli_entry *top_dir)
{
    bcmos_errno err = BCM_ERR_OK;

    if (!gpon_utils_is_registered)
    {
        gpon_utils_is_registered = BCMOS_TRUE;

        /* Subscribe for device change indication */
        err = bcmolt_dev_sel_ind_register(bcmolt_user_appl_gpon_utils_device_change_ind);
    }
    return err ? err : bcmolt_user_appl_gpon_utils_create(top_dir);
}

static bcmos_errno bcmolt_user_appl_gpon_utils_create(bcmcli_entry *top_dir)
{
    static bcmcli_enum_val generated_packet_pattern_table[] =
    {
        { .name = "byte_cycle", .val = GENERATED_PACKET_PATTERN_BYTE_CYCLE },
        { .name = "word_cycle", .val = GENERATED_PACKET_PATTERN_WORD_CYCLE },
        { .name = "const",      .val = GENERATED_PACKET_PATTERN_CONST },
        BCMCLI_ENUM_LAST
    };

    static bcmcli_parm_value gem_port_ids[MAX_GEM_PORTS_FOR_SEND];
    static bcmcli_parm_value onu_ids[MAX_ONUS_FOR_SEND];

    bcmcli_entry *dir;

    if (bcmcli_dir_find(top_dir, "gpon"))
    {
        return BCM_ERR_OK;
    }

    gpon_utils_cli_dir_cli_destroy();

    dir = bcmcli_dir_add(top_dir, "gpon", "Common GPON/XGPON functions", BCMCLI_ACCESS_ADMIN, NULL);
    BCMOS_CHECK_RETURN_ERROR(!dir, BCM_ERR_NOMEM);

    BCMCLI_MAKE_CMD(
        dir,
        "build_cpu_packet",
        "Build and save CPU packet",
        build_cpu_packet_cb,
        BCMCLI_MAKE_PARM_ENUM("calc_crc", "Auto-calculate CRC", bcmcli_enum_bool_table, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM_RANGE(
            "packet_size", "Full packet size", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE, 0, MAX_PACKET_SIZE),
        BCMCLI_MAKE_PARM_ENUM("pattern", "Background pattern", generated_packet_pattern_table, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM_RANGE("const_value", "Const value", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE, 0, 0xFF),
        BCMCLI_MAKE_PARM("eth_da", "Ethernet destination address", BCMCLI_PARM_MAC, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM("eth_sa", "Ethernet source address", BCMCLI_PARM_MAC, BCMCLI_PARM_FLAG_NONE));

    BCMCLI_MAKE_CMD(
        dir,
        "build_omci_packet",
        "Build and save OMCI packet",
        build_omci_packet_cb,
        BCMCLI_MAKE_PARM_ENUM("calc_crc", "Auto-calculate CRC", bcmcli_enum_bool_table, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM_RANGE(
            "packet_size", "Full packet size", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE, 0, MAX_PACKET_SIZE),
        BCMCLI_MAKE_PARM_ENUM("pattern", "Background pattern", generated_packet_pattern_table, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM_RANGE("const_value", "Const value", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE, 0, 0xFF));

    BCMCLI_MAKE_CMD(
        dir,
        "send_to_gem",
        "Send saved CPU/OMCI packet to GEM port(s)",
        send_to_gem_cb,
        BCMCLI_MAKE_PARM("device", "Device ID", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM("pon_ni", "PON NI", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM_ARRAY(
            "gem",
            "GEM port IDs, comma separated",
            BCMCLI_PARM_UNUMBER,
            BCMCLI_PARM_FLAG_NONE,
            MAX_GEM_PORTS_FOR_SEND,
            gem_port_ids),
        BCMCLI_MAKE_PARM("count", "Number of packets (default 1)", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_OPTIONAL));

    BCMCLI_MAKE_CMD(
        dir,
        "send_to_onu",
        "Send saved CPU/OMCI packet to ONU(s) (OMCI GEM port)",
        send_to_onu_cb,
        BCMCLI_MAKE_PARM("device", "Device ID", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM("pon_ni", "PON NI", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM_ARRAY(
            "onu",
            "ONU IDs, comma separated",
            BCMCLI_PARM_UNUMBER,
            BCMCLI_PARM_FLAG_NONE,
            MAX_ONUS_FOR_SEND,
            onu_ids),
        BCMCLI_MAKE_PARM("count", "Number of packets (default 1)", BCMCLI_PARM_UNUMBER, BCMCLI_PARM_FLAG_OPTIONAL));

    BCMCLI_MAKE_CMD_NOPARM(
        dir,
        "dump_packet",
        "Print saved CPU/OMCI packet data",
        dump_packet_cb);

    gpon_utils_cli_dir = dir;
    gpon_utils_cli_top_dir = top_dir;
    return BCM_ERR_OK;
}
