/******************************************************************
 * @file  log_interface.s.c
 * @brief:    物理层log相关函数定义
 * @author: guicheng.liu
 * @Date 2021年3月9日
 * COPYRIGHT NOTICE: (c) smartlogictech. All rights reserved. 
 * Change_date         Owner         Change_content
 * 2021年3月9日        guicheng.liu       create file

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

/**************************include******************************/
#include <type_define.h>
#include "log_interface.h"
#include "common.h"
#include "msg_interface.h"
#include "osp_ape.h"
#include "drv_ape.h"

/**************************function******************************/
log_level_e g_log_level = INFO;
uint32_t g_log_NO = 0;

uint8_t   *g_ape_log_pool = NULLPTR;   
uint8_t   *g_ape_log_buffer[64] = {NULLPTR};
uint32_t   g_ape_log_buf_index = 0;
uint32_t   g_ape_log_buf_min_addr;
uint32_t   g_ape_log_buf_max_addr;

//自定义空间的log头定义
extern uint32_t g_ape_log_header[(LOG_HEADER_SIZE + 3)>>2];
//静态申请log空间
extern uint32_t g_ape_log_static_buf[LOG_DM_BUF_NUM * LOG_MAX_LEN_WORD];
 /*!   
 * @brief: 静态开16K空间，作为log buffer使用
 * @author:  bo.liu
 * @Date:  2021年3月12日
 */
void  log_pool_init()
{
	int32_t   buf_index = 0; 

    g_ape_log_pool = (uint8_t *)g_ape_log_static_buf;//dmalloc_unit(LOG_DM_BUF_NUM*(256+16), DM2);

    for(buf_index = 0; buf_index < LOG_DM_BUF_NUM; buf_index++)
    {
		g_ape_log_buffer[buf_index] = g_ape_log_pool + buf_index * LOG_MAX_LEN_BYTE;
    }
    g_ape_log_buf_min_addr = (uint32_t)g_ape_log_buffer[0] + LOG_TOTAL_HDR_SIZE;
    g_ape_log_buf_max_addr = (uint32_t)g_ape_log_buffer[LOG_DM_BUF_NUM - 1] + LOG_TOTAL_HDR_SIZE;
}


void set_log_level(log_level_e level)
{
    if ((CMD <= level) && (DEBUG >= level))
    {
        g_log_level = level;
    }
    else
    {
        //osp_printf("invalid value\n");
    }
}

char *log_buf_alloc_static()
{
	char *msg_ptr;
	smart_int_disable();
	//OSP_INTER_LOCK(); 等DD提供接口后打开注释
	g_ape_log_buf_index = (g_ape_log_buf_index + 1)&(LOG_DM_BUF_NUM - 1); 
	msg_ptr =  (char *)(g_ape_log_buffer[g_ape_log_buf_index] + LOG_TOTAL_HDR_SIZE);//预留4+2个int for DD Header & PHY Header
	smart_int_enable();
	return msg_ptr;
}


void log_output(uint8_t level, uint8_t taskId, uint16_t msg_type, 
                     uint16_t sfn, uint16_t slot, uint16_t slot_offset, 
					uint8_t buf_type,  uint16_t msg_len, char* msg_body_addr)
{
    char* msg_hdr = (char*)g_ape_log_header;
	log_msg_header_t *log_hdr = (log_msg_header_t *)(&msg_hdr[LOG_DD_HEADER_SIZE]);//预留平台头
    char* msg_tmp[2] = {NULLPTR};
    uint32_t msg_len_tmp[2] = {0};

    if ((level > g_log_level) || (msg_len > LOG_MAX_CONTENT_SIZE))
    {
        return;
    }

    if(0 == buf_type)
    {
        if((g_ape_log_buf_min_addr > (uint32_t)msg_body_addr)
        ||(g_ape_log_buf_max_addr  < (uint32_t)msg_body_addr))
        {
            return;
        }
        msg_hdr = (msg_body_addr - LOG_TOTAL_HDR_SIZE);
        log_hdr = (log_msg_header_t *)(msg_body_addr - LOG_HEADER_SIZE);
    }
	smart_int_disable();
	
	log_hdr->sync_flag = 0x13C;
	log_hdr->msg_level = level;
    log_hdr->msg_type = msg_type & 0xFFF;
    log_hdr->msg_len = msg_len;
    log_hdr->sfn = sfn;
    log_hdr->slot = slot;
    log_hdr->slot_offset = slot_offset & 0x3FF;
    log_hdr->msgNo = (g_log_NO++) & 0x7;

    //buf_type=0:表示使用log模块申请的内存
    //buf_type=1:表示log header使用log模块申请的内存,log body使用各个链路的DM内存
	if (0 == buf_type)
	{
        osp_sendLog_print(level, (char*)log_hdr, LOG_HEADER_SIZE + msg_len, 0);
    	osp_phy_msg_send(msg_hdr, LOG_TOTAL_HDR_SIZE + msg_len);
    }
    else
    {
        msg_len_tmp[0] = LOG_TOTAL_HDR_SIZE;
        msg_len_tmp[1] = msg_len;
        msg_tmp[0] = (char*)msg_hdr;
        msg_tmp[1] = (char*)msg_body_addr;

        osp_sendLog_print(level, (char*)log_hdr, LOG_HEADER_SIZE + msg_len, 0);
        osp_phy_multi_msgs_send(UCP4008_OSP_LOG, msg_tmp, msg_len_tmp, 2);
    }

	smart_int_enable();
}

void log_sprintf(log_level_e level, const char *fmt, ...)
{
    char *buf = NULLPTR;
    char* msg = NULLPTR;
    va_list args;
    int str_len = 0;

    if (level > g_log_level)
    {
        return;
    }

    buf = (char *)log_buf_alloc_static() - LOG_HEADER_SIZE;
    msg = buf - LOG_DD_HEADER_SIZE;

    va_start(args, fmt);
    vsprintf(buf, fmt, args);
    va_end(args);
    str_len = osp_strlen(buf);

    if (LOG_MAX_CONTENT_SIZE < str_len)
    {
        return;
    }
    
	smart_int_disable();
    osp_sendLog(level, (char*)buf, str_len, 0);
    //osp_phy_msg_send(UCP4008_OSP_LOG, (char*)msg, str_len+LOG_DD_HEADER_SIZE);
	smart_int_enable();
}