/*
  <: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 "bcmos_system.h"
#include "bcmolt_model_types.h"
#include "bcmolt_epon_oam_types.h"
#include "bcmolt_user_appl_dpoe_sec.h"
#include "dpoe_sec_fsm.h"

static bcmos_bool is_running = BCMOS_FALSE;

static bcmos_bool cert_authority_trust_placeholder(dpoe_sec_link_rec* link_rec)
{
    BCM_LOG(INFO, dpoe_sec_log_id[link_rec->device], "This function should validate the certificate information stored in the link record and decide whether to accept this authentication.\n");
    return BCMOS_TRUE;
}

static void fsm_complete_placeholder(bcmolt_devid device, bcmolt_epon_link_key link_key, bcmos_errno status)
{
    if (status == BCM_ERR_OK)
    {
        BCM_LOG(INFO, dpoe_sec_log_id[device], "The DPoE Security FSM completed successfully. This link can now be configured for service.\n");
    }
    else
    {
        BCM_LOG(INFO, dpoe_sec_log_id[device], "The DPoE Security FSM failed due to %s (%d). Appropriate action should be taken to correct this error.\n", bcmos_strerror(status), status);
    }
}

#ifdef ENABLE_CLI
static bcmos_errno dpoe_sec_cli_auth(bcmcli_session *session, const bcmcli_cmd_parm parm[], uint16_t n_parms)
{
    bcmolt_epon_link_key link_key;
    dpoe_sec_fsm_start_data cfg;

    link_key.epon_ni = (bcmolt_epon_ni)bcmcli_find_named_parm(session, "pon")->value.unumber;
    link_key.mac_address = bcmcli_find_named_parm(session, "onu")->value.mac;
    cfg.enc_mode = (bcmolt_epon_oam_dpoe_encryption_mode)bcmcli_find_named_parm(session, "mode")->value.enum_val;
    cfg.auth = BCMOS_TRUE;

    return dpoe_sec_fsm_link_start(current_device, link_key, &cfg);
}
#endif

void bcmolt_user_appl_dpoe_sec_cli_init(bcmcli_entry *top_dir)
{
#ifdef ENABLE_CLI
    static const char *dir_name = "dpoe_sec";

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

    bcmcli_entry *dpoe_sec_dir = bcmcli_dir_add(top_dir, dir_name, "DPoE Security", BCMCLI_ACCESS_ADMIN, NULL);
    BUG_ON(NULL == dpoe_sec_dir);

    static bcmcli_enum_val enc_mode_table[] =
    {
        {"none", (long)BCMOLT_EPON_OAM_DPOE_ENCRYPTION_MODE_NONE},
        {"1down", (long)BCMOLT_EPON_OAM_DPOE_ENCRYPTION_MODE_ONE_DOWN},
        {"10down", (long)BCMOLT_EPON_OAM_DPOE_ENCRYPTION_MODE_TEN_DOWN},
        {"10bi", (long)BCMOLT_EPON_OAM_DPOE_ENCRYPTION_MODE_TEN_BI},
        BCMCLI_ENUM_LAST
    };

    BCMCLI_MAKE_CMD(dpoe_sec_dir, "auth", "Authenticate ONU", dpoe_sec_cli_auth,
        BCMCLI_MAKE_PARM("pon", "PON NI", BCMCLI_PARM_UDECIMAL, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM("onu", "ONU MAC", BCMCLI_PARM_MAC, BCMCLI_PARM_FLAG_NONE),
        BCMCLI_MAKE_PARM_ENUM("mode", "Encryption mode", enc_mode_table, BCMCLI_PARM_FLAG_NONE));
#endif
}

void bcmolt_user_appl_dpoe_sec_process_proxy_rx(bcmolt_devid device_id, bcmolt_proxy_rx *proxy_rx)
{
    const bcmolt_epon_link_frame_captured *cap = (bcmolt_epon_link_frame_captured*)proxy_rx;

    if ((BCMOLT_OBJ_ID_EPON_LINK == proxy_rx->hdr.obj_type) &&
        (BCMOLT_EPON_LINK_PROXY_RX_ID_FRAME_CAPTURED == proxy_rx->hdr.subgroup))
    {
        if ((cap->data.frame.val[12] == 0x88) &&
            (cap->data.frame.val[13] == 0x09) &&
            (cap->data.frame.val[14] == 0x03))
        {
            uint8_t *frame_copy;

            frame_copy = bcmos_alloc(cap->data.frame.len);
            memcpy(frame_copy, cap->data.frame.val, cap->data.frame.len);

            dpoe_sec_fsm_link_rx_oam(device_id, cap->key, frame_copy, cap->data.frame.len);
        }
    }
    else
    {
        return; /* not a frame captured on a link - ignore */
    }
}

void bcmolt_user_appl_dpoe_sec_init(void)
{
    if (is_running)
    {
        return;
    }

    dpoe_sec_fsm_init(cert_authority_trust_placeholder, fsm_complete_placeholder);

    is_running = BCMOS_TRUE;
}

