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

:>
 */

/*
 * This file is contains the customer-provided code.
 * This file is provided as an example.
 * The customer may change the file path/names.
 * The customer may change the file access functions.
 * The customer may adjust the data block size.
 * Adding a new image type requires the object model change and sync up with
 * the embedded size, which should be done by the Broadcom engineering.
 */

#include <bcmolt_conv.h>
#include "bcmolt_image_transfer.h"
#include "bcmolt_image_transfer_user.h"
#include "bcmolt_utils.h"

/* example names for debugging purpose only */
#define BOOT_FILE "/opt/bcm68620/bcm68620_boot.bin"
#define APPL_FILE "/opt/bcm68620/bcm68620_appl.bin"
#define ITU_PON_ONU_FW_FILE "/opt/bcm68620/gpon_onu_fw.w"
#define EPON_ONU_FW_FILE "/opt/bcm68620/epon_onu_fw.tkf"

static int2str_t image_type2str[] =
{
    {BCMOLT_DEVICE_IMAGE_TYPE_BOOTLOADER, BOOT_FILE},
    {BCMOLT_DEVICE_IMAGE_TYPE_APPLICATION, APPL_FILE},
    {BCMOLT_DEVICE_IMAGE_TYPE_ITU_PON_ONU_FIRMWARE, ITU_PON_ONU_FW_FILE},
    {BCMOLT_DEVICE_IMAGE_TYPE_EPON_ONU_FIRMWARE, EPON_ONU_FW_FILE},
    {-1}
};

/** Get the device file name.
 * 
 * \param[in]   image_type      Image type. defined in the object model.
 * 
 * \return      string          Pointer to device image name, including the path.
 */
const char *bcmuser_device_image_name_get(bcmolt_device_image_type image_type)
{
    if (image_type < BCMOLT_DEVICE_IMAGE_TYPE__NUM_OF)
    {
        return int2str(image_type2str, image_type);
    }
    return NULL;
}

/** Open a file with given image type.
 *
 * \param[in]   image_type      Image type. defined in the object model.
 * \param[out]  fpp             File pointer
 *
 * \return      bcmos_errno     Error code
 */
static bcmos_errno bcmuser_image_transfer_file_open(bcmolt_device_image_type image_type, FILE **fpp)
{
    bcmos_errno rc = BCM_ERR_PARM;

    if (image_type < BCMOLT_DEVICE_IMAGE_TYPE__NUM_OF)
    {
        FILE *fp;
        const char *fname = bcmuser_device_image_name_get(image_type);
        fp = fopen(fname, "rb");
        if (fp != NULL)
        {
            *fpp = fp;
            rc = BCM_ERR_OK;
        }
    }
    return rc;
}

/** Get the size of the file. 
 * 
 * \param[in]   device          Device ID
 * \param[in]   image_type      Image type. defined in the object model.
 * \param[out]  fsize           File size
 * 
 * \return      bcmos_errno 
 */
bcmos_errno bcmuser_image_transfer_file_size_get(bcmolt_devid device,
    bcmolt_device_image_type image_type, uint32_t *fsize)
{
    FILE *fp;
    long fp_prev;
    bcmos_errno rc = BCM_ERR_OK;
    (void)device;

    rc = bcmuser_image_transfer_file_open(image_type, &fp);
    if (rc == BCM_ERR_OK)
    {
        fp_prev = ftell(fp);
        BUG_ON(fp_prev < 0);
        BUG_ON(fseek(fp, 0, SEEK_END) != 0);
        *fsize = ftell(fp);
        BUG_ON(fseek(fp, fp_prev, SEEK_SET) != 0); /* go back to where we were. */
        BUG_ON(fclose(fp) != 0);
    }
    return rc;
}

/** Read data from given offset.
 *
 * \param[in]   device          Device ID
 * \param[in]   image_type      Image type. defined in the object model.
 * \param[in]   offset          File position indicator
 * \param[out]  buf             Buffer to store the data
 * \param[in]   buf_size        Buffer size
 *
 * \return      Bytes read
 */
int bcmuser_image_transfer_read_data(bcmolt_devid device, bcmolt_device_image_type image_type,
    uint32_t offset, uint8_t *buf, uint32_t buf_size)
{
    FILE *fp;
    uint32_t bytes_read = 0;
    (void)device;

    if (bcmuser_image_transfer_file_open(image_type, &fp) == BCM_ERR_OK)
    {
        BUG_ON(fseek(fp, 0, SEEK_END) != 0);
        if (offset < ftell(fp))
        {
            BUG_ON(fseek(fp, offset, SEEK_SET) != 0);
            bytes_read = fread(buf, 1, buf_size, fp);
        }
        BUG_ON(fclose(fp) != 0);
    }
    return bytes_read;
}

/** Get the unit size of the transfer data block.
 *
 * \return      Size of the block in bytes.
 */
uint32_t bcmuser_image_transfer_block_size_get(void)
{
    return MFTP_DATA_BLOCK_SIZE;
}

/** Returns the CRC32 checksum of entire image.
 * 
 * \param[in]   device          Device ID
 * \param[in]   image_type      Image type. defined in the object model.
 * 
 * \return      CRC32 checksum 
 */
uint32_t bcmuser_image_transfer_crc_get(bcmolt_devid device, bcmolt_device_image_type image_type)
{
    FILE *fp;
    uint32_t crc = 0;
    (void)device;

    if (bcmuser_image_transfer_file_open(image_type, &fp) == BCM_ERR_OK)
    {
        while (1)
        {
            char buf[512]; /* any size is OK. */
            uint32_t bytes_read;

            bytes_read = fread(buf, 1, sizeof(buf), fp);
            if (bytes_read == 0)
                break;
            crc = eth_calc_crc32(crc, buf, bytes_read);
        }
        BUG_ON(fclose(fp) != 0);
    }
    return crc;
}

/** Process the notification from the image transfer module.
 *
 * \param[in]   device          Device ID
 * \param[in]   image_type      Image type. defined in the object model. 
 * \param[in]   block_num       last block number 
 * \param[in]   status          Image transfer status 
 */
void bcmuser_image_transfer_notification_rx(bcmolt_devid device,
    bcmolt_device_image_type image_type, uint32_t block_num,
    bcmolt_image_transfer_status status)
{
    const char *str = bcmolt_user_mftp_status_to_str(status);
    bcmos_printf("Image transfer: %s: type=%u block=%u\n", str, image_type, block_num);
}

