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

   Copyright (c) 2014 Broadcom Corporation
   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 <bcmcli.h>
#include <bcmolt_model_types.h>
#include <bcmolt_msg.h>
#include <bcmolt_api.h>
#include <bcm_api_cli_helpers.h>
#include "bcmolt_image_transfer.h"
#include "bcmolt_image_transfer_cli.h"

static bcmos_bool bcmolt_user_appl_device_state_is_ready(bcmolt_devid device)
{
    bcmos_errno err;
    bcmolt_device_cfg cfg = {};
    bcmolt_device_key key = {};

    BCMOLT_CFG_INIT(&cfg, device, key);
    BCMOLT_CFG_PROP_GET(&cfg, device, state);
    err = bcmolt_cfg_get(device, &cfg.hdr);
    return (err == BCM_ERR_OK) && (cfg.data.state == BCMOLT_DEVICE_STATE_READY);
}

/** start the image transfer.
 */
static bcmos_errno bcmolt_user_appl_cli_image_transfer_start(bcmcli_session *session,
    const bcmcli_cmd_parm parms[], uint16_t n_parms)
{
    bcmolt_device_image_type image_type;
    bcmolt_devid device = 0;
    bcmos_errno err;

    if (!bcmolt_user_appl_device_state_is_ready(device))
    {
        bcmcli_session_print(session, "device not connected\n");
        return BCM_ERR_NOT_CONNECTED;
    }

    image_type = bcmcli_find_named_parm(session, "image_type")->value.unumber;

    err = bcmolt_user_mftp_start(device, image_type);
    if (err != BCM_ERR_OK)
    {
        bcmcli_session_print(session, "%s\n", bcmos_strerror(err));
    }
    return err;
}

bcmos_errno bcmolt_user_appl_cli_image_transfer_init(bcmcli_entry *top_dir)
{
    bcmcli_entry *dir = bcmcli_dir_add(top_dir, "image_transfer",
        "Image Transfer user application", BCMCLI_ACCESS_ADMIN, NULL);
    BCMOS_CHECK_RETURN_ERROR(!dir, BCM_ERR_NOMEM);

    BCMCLI_MAKE_CMD(dir, "start", "Start Image Transfer application", bcmolt_user_appl_cli_image_transfer_start,
        BCMCLI_MAKE_PARM_ENUM("image_type", "Image type", bcmolt_device_image_type_string_table, BCMCLI_PARM_FLAG_NONE));

    return BCM_ERR_OK;
}

