/******************************************************************
 * @file  phy_msg_func.s.c
 * @brief:    [file description] 
 * @author: guicheng.liu
 * @Date 2022年6月28日
 * COPYRIGHT NOTICE: (c) smartlogictech. All rights reserved. 
 * Change_date         Owner         Change_content
 * 2022年6月28日        guicheng.liu       create file

*****************************************************************/

/**************************include******************************/
#include <type_define.h>
#include "phy_msg_func.h"
#include "msg_interface.h"
#include "common.h"
#include "log_interface.h"
#include "phy_macro.h"

/**************************function******************************/

//msg_ring_buffer_t g_phy_msg_buffer[UCP4008_TRAFFIC_MAX_NUM];

/*!   
* @brief:  初始化ring buffer
* @author:  guicheng.liu
* @Date:  2022年6月29日
*/
void msg_buffer_init()
{
    msg_ring_buffer_t* ring_buffer = NULLPTR;

    for (uint32_t i = 0; i < MAX_CELL_NUM; i++)
    {
        ring_buffer = &g_phy_msg_buffer[i];
        STORE_EX_W(&ring_buffer->num, MAX_RING_BUFFER_NUM);
        STORE_EX_W(&ring_buffer->head, 0);
        STORE_EX_W(&ring_buffer->tail, 0);

        //memset(ring_buffer->buffer, 0, MAX_RING_BUFFER_NUM*sizeof(buffer_info_t));
    }
}

/*!   
* @brief:  判断队列是否为空
* @author:  guicheng.liu
* @Date:  2022年6月29日
* @param: queue_num :        [队列号]
*/
bool msg_buffer_empty(uint32_t queue_num)
{
    msg_ring_buffer_t* ring_buffer = &g_phy_msg_buffer[queue_num];;

    return (LOAD_EX_W(&ring_buffer->head) == LOAD_EX_W(&ring_buffer->tail));
}

/*!   
* @brief:  判断当前ring buffer是否满了，用于写操作前的判断
* @author:  guicheng.liu
* @Date:  2022年6月29日
* @param: *ring_buffer :     [buffer 指针]
*/
bool msg_buffer_full(msg_ring_buffer_t *ring_buffer)
{
    int tmp_len = LOAD_EX_W(&ring_buffer->head) - LOAD_EX_W(&ring_buffer->tail);

    //tmp_len = ring_buffer->head - ring_buffer->tail;

    //如果要写的位置紧挨在可读位置后面，则判定为满
    if((-1 == tmp_len) || 
        ((LOAD_EX_W(&ring_buffer->num) - 1) == tmp_len))
    {
        return true;
    }
    else
    {
        return false;
    }
}


/*!   
* @brief:  消息入队
* @author:  guicheng.liu
* @Date:  2022年6月29日
* @param: queue_num :        [队列号]
* @param: buf :              [指针]
* @param: len :              [长度]
*/
void enque_msg_buffer(uint32_t queue_num,
                            uint32_t el_ind,
                            char* buf, 
                            uint32_t len)
{
    msg_ring_buffer_t *ring_buffer = &g_phy_msg_buffer[queue_num];
    int head = LOAD_EX_W(&ring_buffer->head);
    int num = LOAD_EX_W(&ring_buffer->num);

    if(msg_buffer_full(ring_buffer))
    {
        LOG_ERROR_S("Enque Msg Fail, queue_num:%u\n", queue_num);
        return;
    }

    STORE_EX_W(&ring_buffer->buffer[head].el_ind, el_ind);
    STORE_EX_W(&ring_buffer->buffer[head].len, len);
    STORE_EX_W(&ring_buffer->buffer[head].buff, (uint32_t)buf);

    head = head + 1;

    if(head == num)
    {
	    STORE_EX_W(&ring_buffer->head, 0);
    }
    else
    {
        STORE_EX_W(&ring_buffer->head, head);
    }
}


 /*!   
 * @brief:  出队函数
 * @author:  guicheng.liu
 * @Date:  2022年6月29日
 * @param: queue_num :        [队列号]
 * @param: buf :              [指针]
 * @param: len :              [长度]
 */
int deque_msg_buffer(uint32_t queue_num, 
                            uint32_t* el_ind,
                            char** buf, 
                            uint32_t* len)
{
    msg_ring_buffer_t *ring_buffer = &g_phy_msg_buffer[queue_num];
    int tail = LOAD_EX_W(&ring_buffer->tail);
    int num = LOAD_EX_W(&ring_buffer->num);

    if (msg_buffer_empty(queue_num))
    {
        return 0;
    }

    *el_ind = LOAD_EX_W(&ring_buffer->buffer[ring_buffer->tail].el_ind);
    *len = LOAD_EX_W(&ring_buffer->buffer[ring_buffer->tail].len);
    *buf = (char*)LOAD_EX_W(&ring_buffer->buffer[ring_buffer->tail].buff);

    tail++;

    if(tail == num)
    {
	    STORE_EX_W(&ring_buffer->tail, 0);
    }
    else
    {
        STORE_EX_W(&ring_buffer->tail, tail);
    }

    return 1;
}

