/*
 * Copyright (c) 2014, Mentor Graphics Corporation
 * Copyright (c) 2015 Xilinx, Inc.
 * Copyright (c) 2016 Freescale Semiconductor, Inc.
 * Copyright 2016-2019 NXP
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice,
 *    this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice,
 *    this list of conditions and the following disclaimer in the documentation
 *    and/or other materials provided with the distribution.
 * 3. Neither the name of the copyright holder nor the names of its
 *    contributors may be used to endorse or promote products derived from this
 *    software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#include "rpmsg_lite.h"
#include "rpmsg_queue.h"

typedef struct
{
    uint32_t src;
    void *data;
    uint32_t len;
} rpmsg_queue_rx_cb_data_t;

int32_t rpmsg_queue_rx_cb(void *payload, uint32_t payload_len, uint32_t src, void *priv)
{
    rpmsg_queue_rx_cb_data_t msg;

    RL_ASSERT(priv != RL_NULL);

    msg.data = payload;
    msg.len  = payload_len;
    msg.src  = src;

    /* if message is successfully added into queue then hold rpmsg buffer */
    if (0 != env_put_queue(priv, &msg, 0))
    {
        /* hold the rx buffer */
        return RL_HOLD;
    }

    return RL_RELEASE;
}

rpmsg_queue_handle rpmsg_queue_create(struct rpmsg_lite_instance *rpmsg_lite_dev)
{
    int32_t status;
    void *q = RL_NULL;

    if (rpmsg_lite_dev == RL_NULL)
    {
        return RL_NULL;
    }

    /* create message queue for channel default endpoint */
    status = env_create_queue(&q, (int32_t)rpmsg_lite_dev->rvq->vq_nentries, (int32_t)sizeof(rpmsg_queue_rx_cb_data_t));
    if ((status != 0) || (q == RL_NULL))
    {
        return RL_NULL;
    }

    return ((rpmsg_queue_handle)q);
}

int32_t rpmsg_queue_destroy(struct rpmsg_lite_instance *rpmsg_lite_dev, rpmsg_queue_handle q)
{
    if (rpmsg_lite_dev == RL_NULL)
    {
        return RL_ERR_PARAM;
    }

    if (q == RL_NULL)
    {
        return RL_ERR_PARAM;
    }
    env_delete_queue((void *)q);
    return RL_SUCCESS;
}

int32_t rpmsg_queue_recv(struct rpmsg_lite_instance *rpmsg_lite_dev,
                         rpmsg_queue_handle q,
                         uint32_t *src,
                         char *data,
                         uint32_t maxlen,
                         uint32_t *len,
                         uint32_t timeout)
{
    rpmsg_queue_rx_cb_data_t msg = {0};
    int32_t retval               = RL_SUCCESS;

    if (rpmsg_lite_dev == RL_NULL)
    {
        return RL_ERR_PARAM;
    }
    if (q == RL_NULL)
    {
        return RL_ERR_PARAM;
    }
    if (data == RL_NULL)
    {
        return RL_ERR_PARAM;
    }

    /* Get an element out of the message queue for the selected endpoint */
    if (0 != env_get_queue((void *)q, &msg, timeout))
    {
        if (src != RL_NULL)
        {
            *src = msg.src;
        }
        if (len != RL_NULL)
        {
            *len = msg.len;
        }

        if (maxlen >= msg.len)
        {
            env_memcpy(data, msg.data, msg.len);
        }
        else
        {
            retval = RL_ERR_BUFF_SIZE;
        }

        /* Release used buffer. */
        return ((RL_SUCCESS == rpmsg_lite_release_rx_buffer(rpmsg_lite_dev, msg.data)) ? retval : RL_ERR_PARAM);
    }
    else
    {
        return RL_ERR_NO_BUFF; /* failed */
    }
}

int32_t rpmsg_queue_recv_nocopy(struct rpmsg_lite_instance *rpmsg_lite_dev,
                                rpmsg_queue_handle q,
                                uint32_t *src,
                                char **data,
                                uint32_t *len,
                                uint32_t timeout)
{
    rpmsg_queue_rx_cb_data_t msg = {0};

    if (rpmsg_lite_dev == RL_NULL)
    {
        return RL_ERR_PARAM;
    }
    if (data == RL_NULL)
    {
        return RL_ERR_PARAM;
    }
    if (q == RL_NULL)
    {
        return RL_ERR_PARAM;
    }

    /* Get an element out of the message queue for the selected endpoint */
    if (0 != env_get_queue((void *)q, &msg, timeout))
    {
        if (src != RL_NULL)
        {
            *src = msg.src;
        }
        if (len != RL_NULL)
        {
            *len = msg.len;
        }

        *data = msg.data;

        return RL_SUCCESS; /* success */
    }

    return RL_ERR_NO_BUFF; /* failed */
}

int32_t rpmsg_queue_nocopy_free(struct rpmsg_lite_instance *rpmsg_lite_dev, void *data)
{
    if (rpmsg_lite_dev == RL_NULL)
    {
        return RL_ERR_PARAM;
    }
    if (data == RL_NULL)
    {
        return RL_ERR_PARAM;
    }

    /* Release used buffer. */
    return ((RL_SUCCESS == rpmsg_lite_release_rx_buffer(rpmsg_lite_dev, data)) ? RL_SUCCESS : RL_ERR_PARAM);
}

int32_t rpmsg_queue_get_current_size(rpmsg_queue_handle q)
{
    if (q == RL_NULL)
    {
        return RL_ERR_PARAM;
    }

    /* Return actual queue size. */
    return env_get_current_queue_size((void *)q);
}
