#define _GNU_SOURCE /*使用get_current_dir_name 编译告警，该宏的定义应该在unistd.h之前*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <execinfo.h>
#include <syslog.h>
#include <sys/types.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/sysinfo.h>
#include "osp.h"
#include "ospSoftQue.h"
#include "ospShell.h"
#include "ucp_printf.h"
#include "ospUdp.h"



void *g_OspLogSem = NULL;


int32_t osp_base_logid;
uint32_t   log_rand;
uint32_t   g_ulApeLogMode       = 0; /*0: ape log日志写入文件 1: 网口输出ape log 2:ape log日志shell打印输出*/
uint32_t   g_ulArmLogMode       = 0; /*0: arm log日志写入文件 1: 网口输出arm log 2:arm log日志shell打印输出*/
uint8_t    g_ucPlatformMode     = 0; /*0: platform log日志写入文件 1: 网口输出platform log 2:platform log日志shell打印输出*/
uint8_t    g_time_now[128];
uint8_t    g_ucFflushEnable     = 0;
int32_t    net_log_txudp_id     = -1; /*吐网口log id*/

Osp_Server_Head gst_server_log;
extern uint8_t guc_print_level;
extern char *gp_dump_buf;
osp_log_file_cfg log_file_cfg_table[MAX_LOG_CFG_NUM][4];

void osp_get_current_time(void)
{   
    OSP_RTCTIME osptime;
   
    osp_get_rtc_time(&osptime);
    sprintf((char *)g_time_now,  \
        "[%04d-%02d-%02d-%02d:%02d:%02d:%02d]", \
        osptime.year, osptime.month, osptime.day, \
        osptime.hour, osptime.minute, osptime.second, osptime.usecond);
}

uint32_t osp_get_msgtype_id(uint32_t msg_type)
{
    uint32_t type = 0;

    switch(msg_type)
    {
        case 0x60:
            type = 0;
        break;
        case 0x61:
            type = 1;
        break;
        case 0x62:
            type = 2;
        break;
        case 0x63:
            type = 3;
        break;
        default:
            type = 0;
        break;
    }

    return type;
}

void osp_get_msgtype_name(uint32_t msg_type, char *msg_name)
{
    if(NULL == msg_name)
    {
        return;
    }
    
    switch(msg_type)
    {
        case 0x60:
            strcpy(msg_name,"str");
        break;
        case 0x61:
            strcpy(msg_name,"bin");
        break;
        case 0x62:
            strcpy(msg_name,"platform");
        break;
        case 0x63:
            strcpy(msg_name,"dm");
        break;
        default:
            strcpy(msg_name,"default");
        break;
    }

    return;
}


int32_t osp_modify_log(uint32_t logid, uint32_t msg_type, uint32_t max_file_size, uint32_t max_file_num)
{
    uint32_t type = 0;
    osp_log_file_cfg (*p_log_file_cfg)[4];
    
    if (max_file_size > 100 || max_file_num > 100)
    {
        UCP_PRINT_ERROR("error:osp_modify_log max_file_szie:%d max_file_num:%d\n", max_file_size, max_file_num);
        return OSP_ERROR;
    }

    if (logid > 15)
    {       
        UCP_PRINT_ERROR("error:osp_modify_log logid:%d\n", logid);
        return OSP_ERROR;
    }

    type = osp_get_msgtype_id(msg_type);
    
    p_log_file_cfg = log_file_cfg_table;
    //p_log_file_cfg = (osp_log_file_cfg *)&log_file_cfg_table[0][0];
    if (p_log_file_cfg[logid][type].valied == 1)
    {
        p_log_file_cfg[logid][type].max_file_size_M   = max_file_size;
        p_log_file_cfg[logid][type].max_file_num      = max_file_num;
    }
    else
    {
        UCP_PRINT_ERROR("error:osp_modify_log valied:%d\n", p_log_file_cfg[logid][type].valied);
        return OSP_ERROR;
    }
    return OSP_OK;
}

int32_t osp_create_log(char *name, uint32_t max_file_szie, uint32_t max_file_num, uint32_t with_time)
{
    uint32_t i;
    uint32_t j;
    osp_log_file_cfg (*p_log_file_cfg)[4];

    if (NULL == g_OspLogSem)
    {
        return OSP_ERROR;
    }
    
    if (name == NULL || max_file_szie < 0 || max_file_num < 0)
    {
        return OSP_ERROR;
    }

    osp_sem_take(g_OspLogSem, -1);

    p_log_file_cfg = log_file_cfg_table;
    // p_log_file_cfg = &log_file_cfg_table[0][0];

    for (i = 0; i < MAX_LOG_CFG_NUM; i++)
    {
        for(j = 0; j< 4; j++)
        {
            if (p_log_file_cfg[i][j].valied == 0)
            {
                p_log_file_cfg[i][j].valied = 1;
                p_log_file_cfg[i][j].max_file_size_M = max_file_szie;
                p_log_file_cfg[i][j].max_file_num    = max_file_num;
                p_log_file_cfg[i][j].with_time       = with_time;
                p_log_file_cfg[i][j].key             = log_rand;

                memcpy(p_log_file_cfg[i][j].logname, name, strlen(name));
            }
        }

    }

    osp_sem_give(g_OspLogSem);
    return OSP_OK;
}


FILE *osp_get_log_file(int32_t logid, uint32_t msg_type)
{
    uint32_t type =0;

    type = osp_get_msgtype_id(msg_type);

    return log_file_cfg_table[logid][type].file;
}

OSP_STATUS osp_update_log(uint32_t len, uint32_t logid, uint32_t msg_type)
{
    osp_log_file_cfg (*p_log_file_cfg)[4];
    char name[150]      = {0};
    char path[150]      = {0};
    char msg_name[10]   = {0};
    int32_t file_idx    = 0;
    uint32_t type       = 0;    
    uint32_t ulfreeram = 0;
    
    if (logid >= MAX_LOG_CFG_NUM || logid < 0)
    {
        return OSP_ERROR;
    }
        
    osp_get_msgtype_name(msg_type, msg_name);
    type = osp_get_msgtype_id(msg_type);
    if (log_file_cfg_table[logid][type].valied == 0)
    {
        return OSP_ERROR;
    }

    p_log_file_cfg = log_file_cfg_table;
    //p_log_file_cfg = &log_file_cfg_table[0][0];
    p_log_file_cfg[logid][type].cur_sum_len += len;

    osp_get_current_time();
    UCP_PRINT_LOG("osp_update_log logid:%d type:0x%x cur_sum_len:%u max_file_size_M:%u !\n", logid,type, p_log_file_cfg[logid][type].cur_sum_len, p_log_file_cfg[logid][type].max_file_size_M);

    /*判断当前系统是否还有足够空间*/
    ulfreeram = osp_get_freeram();
    if((ulfreeram <= FREE_RAM_SIZE) || (1 == g_ucFflushEnable))
    {
        sprintf(name, "rm -rf %s%u-%u-%s.log", p_log_file_cfg[logid][type].logname, (p_log_file_cfg[logid][type].cur_file_idx & 0x7)+1, logid, msg_name);
        system(name);
        UCP_PRINT_LOG("osp_update_log line:%d logid:%d type:0x%x ulfreeram:%u g_ucFflushEnable:%u name:%s\n", __LINE__, logid, type, ulfreeram, g_ucFflushEnable, name);
        osp_log_cfg_reload();
    }
    
    if (p_log_file_cfg[logid][type].cur_sum_len >= p_log_file_cfg[logid][type].max_file_size_M)
    {
        p_log_file_cfg[logid][type].cur_sum_len = 0;
        p_log_file_cfg[logid][type].cur_file_idx++;

        file_idx = p_log_file_cfg[logid][type].cur_file_idx & 0x7;
        if(p_log_file_cfg[logid][type].cur_file_idx >= p_log_file_cfg[logid][type].max_file_num)
        {            
            sprintf(name, "rm -rf %s%u-%u-%s.log", p_log_file_cfg[logid][type].logname, file_idx, logid, msg_name);
            //sprintf(name, "%s-%d-%s-%u-%u-%s.log", p_log_file_cfg[logid][type].logname, getpid(), g_time_now, p_log_file_cfg[logid][type].cur_file_idx, logid, msg_name);
            system(name);
            UCP_PRINT_LOG("osp_update_log line:%d logid:%d type:0x%x remove name:%s\n", __LINE__, logid, type, name);
        }
        
        /*判断当前文件是否合法文件*/
        if(NULL == p_log_file_cfg[logid][type].file)
        {        
            UCP_PRINT_LOG("osp_update_log line:%d logid:%d type:%d file:%p\n", __LINE__, logid, type, p_log_file_cfg[logid][type].file);
            return OSP_ERROR;
        }

        fclose(p_log_file_cfg[logid][type].file);

        osp_get_file_path(p_log_file_cfg[logid][type].logname, path);

        if (access(path, F_OK) != 0)
        {
            osp_mkdirs(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 
        }
        
        sprintf(name, "%s%u-%u-%s.log", p_log_file_cfg[logid][type].logname, file_idx, logid, msg_name);
        //sprintf(name, "%s-%d-%s-%u-%u-%s.log", p_log_file_cfg[logid][type].logname, getpid(), g_time_now, p_log_file_cfg[logid][type].cur_file_idx, logid, msg_name);
        UCP_PRINT_LOG("osp_update_log line:%d logid:%d type:0x%x name:%s\n", __LINE__, logid, type, name);

        /*二进制格式*/
        if(0x61 == msg_type)
        {      
            p_log_file_cfg[logid][type].file   = fopen(name, "wb+");
            /*判断文件是否创建成功*/
            if(p_log_file_cfg[logid][type].file <= 0)
            {
                UCP_PRINT_LOG("osp_update_log line:%d logid:%d type:0x%x name:%s file create fail!\n", __LINE__, logid, type, name);
                return OSP_ERROR;
            }
        }
        else
        {                
            p_log_file_cfg[logid][type].file   = fopen(name, "w+");
            /*判断文件是否创建成功*/
            if(p_log_file_cfg[logid][type].file <= 0)
            {
                UCP_PRINT_LOG("osp_update_log line:%d logid:%d type:0x%x name:%s file create fail!\n", __LINE__, logid, type, name);
                return OSP_ERROR;
            }
        }

    }
    else
    {
        if (NULL == p_log_file_cfg[logid][type].file)
        {
            osp_get_file_path(p_log_file_cfg[logid][type].logname, path);

            if (access(path, F_OK) != 0)
            {
                osp_mkdirs(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 
            }
            
            sprintf(name, "%s%u-%u-%s.log", p_log_file_cfg[logid][type].logname, p_log_file_cfg[logid][type].cur_file_idx, logid, msg_name);
            //sprintf(name, "%s-%d-%s-%u-%u-%s.log", p_log_file_cfg[logid][type].logname, getpid(), g_time_now, p_log_file_cfg[logid][type].cur_file_idx, logid, msg_name);
            UCP_PRINT_LOG("osp_update_log line:%d logid:%d type:0x%x name:%s\n", __LINE__, logid, type, name);

            /*二进制格式*/
            if(0x61 == msg_type)
            {      
                p_log_file_cfg[logid][type].file   = fopen(name, "wb+");
                /*判断文件是否创建成功*/
                if(p_log_file_cfg[logid][type].file <= 0)
                {
                    UCP_PRINT_LOG("osp_update_log line:%d logid:%d type:0x%x name:%s file create fail!\n", __LINE__, logid, type, name);
                    return OSP_ERROR;
                }
            }
            else
            {                
                p_log_file_cfg[logid][type].file   = fopen(name, "w+");
                /*判断文件是否创建成功*/
                if(p_log_file_cfg[logid][type].file <= 0)
                {
                    UCP_PRINT_LOG("osp_update_log line:%d logid:%d type:0x%x name:%s file create fail!\n", __LINE__, logid, type, name);
                    return OSP_ERROR;
                }
            }
        }
    }
    
    return OSP_OK;
}


void osp_log_output(unsigned char level, const char *fmt, ...)
{
    char  acstr[256]  = {0};
    va_list  st_va_list;

    if (level > guc_print_level)
    {
        return;
    }

    va_start(st_va_list, fmt);
    vsprintf((char *)acstr, fmt, st_va_list);
    va_end(st_va_list);

    printf("%s", acstr);

    return;
}



OSP_STATUS osp_dbg_log_ext(char *pbuf, uint32_t buflen, int32_t LogId)
{
#if 0
    Osp_Msg_Head *pNMsg = NULL;

    OSP_RTCTIME osptime;
    char datebuf[100] = {0};

    if ((pbuf == NULL) || (buflen == 0) || (LogId < 0) || (LogId >= MAX_LOG_CFG_NUM) ||
        (log_file_cfg_table[LogId].valied == 0))
    {
        osp_debug_out_with_time(RUN_DEBUG_LEVEL, "osp_dbg_log_ext arg err!\r\n"); 
        return -1;
    }
    
    if (log_file_cfg_table[LogId].with_time)
    {
        osp_get_rtc_time(&osptime);
        sprintf((char *)datebuf,  \
            "[%04d/%02d/%02d-%02d:%02d:%02d:%02d]", \
            osptime.year, osptime.month, osptime.day, \
            osptime.hour, osptime.minute, osptime.second, osptime.usecond);
            
        pNMsg = osp_alloc_msg(strlen(datebuf) + buflen);
        if (pNMsg == NULL)
        {
            return -1;
        }

        pNMsg->MsgType = OSP_STR_LOG;
        pNMsg->MsgSize = strlen(datebuf) + buflen;
        pNMsg->SrcId = LogId;
        pNMsg->DstId = DbgLogTask;  

        memcpy(MSG_HEAD_TO_COMM(pNMsg), datebuf, strlen(datebuf));
        memcpy(MSG_HEAD_TO_COMM(pNMsg) + strlen(datebuf), pbuf, buflen);

    }
    else
    {
        pNMsg = osp_alloc_msg(buflen);
        if (pNMsg == NULL)
        {
            return -1;
        }

        pNMsg->MsgType = OSP_STR_LOG;
        pNMsg->MsgSize = buflen;
        pNMsg->SrcId = LogId;
        pNMsg->DstId = DbgLogTask;  

        memcpy(MSG_HEAD_TO_COMM(pNMsg), pbuf, buflen);

    }

    osp_send_msg(pNMsg);
#endif
    return 0;
}

OSP_STATUS osp_dbg_log(char *pbuf, uint32_t buflen)
{
    return osp_dbg_log_ext(pbuf, buflen, osp_base_logid);
}

OSP_STATUS osp_close_log_file(FILE *file)
{
    if (fclose(file))
    {
        return OSP_ERROR;
    }
    
    return OSP_OK;
}

uint32_t osp_get_freeram(void)
{
    uint32_t ulfreeram = 0;
    struct sysinfo st_info;

    if(0 == sysinfo(&st_info))
    {
        ulfreeram = st_info.freeram;
    }
    
    return ulfreeram;
}


/*默认起始端口号portIDStart=32768，二进制log的portID = portIDStart + core_id * 2；字符串log的portID = portIDStart + core_id * 2 + 1；
  平台网口log默认端口号为32800，ul_port = ul_platform_port + 2*uc_src_core_id;*/
uint32_t osp_get_ape_port(osp_sw_msg_info_t *pMsg)
{
    uint32_t ul_port           = 0;    
    uint32_t ul_start_port     = 32768;
    uint32_t ul_platform_port  = 32800;
    uint8_t  uc_msg_type       = 0;     /* 消息类型 */
    uint8_t  uc_src_core_id    = 0;     /* 源核ID */

    uc_src_core_id = pMsg->u8CoreId;
    uc_msg_type    = pMsg->u8PktType;

    switch (uc_msg_type)
    {
        case OSP_BIN_LOG:
             ul_port = ul_start_port + 2*uc_src_core_id;
             break;
        case OSP_STR_LOG:
             ul_port = ul_start_port + 2*uc_src_core_id + 1;
             break;
        case OSP_PLATFORM_LOG:
             ul_port = ul_platform_port + 2*uc_src_core_id;
             break;
        default:
            break;
    }
    
    UCP_PRINT_LOG("osp_get_ape_port ul_port:%u uc_src_core_id:%u uc_msg_type:0x%x\n", ul_port, uc_src_core_id, uc_msg_type);

    return ul_port;
}

void osp_net_log_proc(char   *pMsg, uint32_t len, uint32_t port)
{
    int32_t  udpid      = 0;

    udpid = osp_get_txudp((char *)&gst_server_log.ip, port);

    if (osp_check_udpid(udpid))
    {
        net_log_txudp_id = udpid;
        //UCP_PRINT_LOG("osp_net_log_proc line:%d udpid:[%u] port:[%u]\n", __LINE__, udpid, port);
    }
    else
    {
        net_log_txudp_id = osp_create_txucp(port, (char *)&gst_server_log.ip);
        //UCP_PRINT_LOG("osp_net_log_proc line:%d udpid:[%u] port:[%u]\n", __LINE__, net_log_txudp_id, port);
    }

    //UCP_PRINT_LOG("osp_net_log_proc line:%d len[%u] udp_id[%u] ip[%s] port[%u]\n", __LINE__, len, net_log_txudp_id, gst_server_log.ip, port);

    osp_udp_send(pMsg, len, net_log_txudp_id);

    return;
}

OSP_STATUS osp_write_diaglog(char *pbuf, uint32_t len ,uint32_t logid, uint32_t msg_type)
{

    int32_t  ret  = 0;
    static FILE *file = NULL;
    uint32_t fd;
    
    if (NULL == g_OspLogSem)
    {
        return OSP_ERROR;
    }
    
    if ((NULL == pbuf) || (0 == len))
    {
        return OSP_ERROR;
    }
    
    osp_sem_take(g_OspLogSem,-1);

    UCP_PRINT_LOG("osp_write_diaglog len[%u] logid[%u] msg_type[0x%x]\n",  len, logid, msg_type);

    ret = osp_update_log(len, logid, msg_type);
    if (ret < 0)
    {
        osp_sem_give(g_OspLogSem);
        return OSP_ERROR;
    }
    
    file = osp_get_log_file(logid, msg_type);
    if (NULL == file)
    {    
        osp_sem_give(g_OspLogSem);
        return OSP_ERROR;
    }

    ret = fwrite(pbuf, sizeof(char), len, file);
    if(ret <= 0)
    {
        UCP_PRINT_LOG("fwrite error ret:%d\n", ret);
        fclose(file);        
        osp_sem_give(g_OspLogSem);
        return OSP_ERROR;
    }

    ret = fflush(file);
    if(OSP_OK != ret)
    {
        UCP_PRINT_LOG("fflush error ret:%d\n", ret);
        g_ucFflushEnable = 1;
    }
    else
    {        
        UCP_PRINT_LOG("fflush ok ret:%d\n", ret);
        g_ucFflushEnable = 0;
    }
    
    fd  = fileno(file);
    ret = fsync(fd);
    if(OSP_OK != ret)
    {
        UCP_PRINT_LOG("fsync error ret:%d\n", ret);
        fclose(file);
        osp_sem_give(g_OspLogSem);
        return OSP_ERROR;
    }
    
    osp_sem_give(g_OspLogSem);

    return OSP_OK;
}

OSP_STATUS osp_arm_net_log_proc(char *pbuf, uint32_t len ,uint32_t logid, uint32_t msg_type)
{
    Osp_Ape_Msg_Head *pmsg_head = NULL;

    if ((NULL == pbuf) || (0 == len))
    {
        return OSP_ERROR;
    }

    pmsg_head = (Osp_Ape_Msg_Head *)malloc(1024);
    if(NULL == pmsg_head)
    {
        UCP_PRINT_ERROR("osp_arm_log_proc ptmp is null\n");
        return OSP_ERROR;
    }

    pmsg_head->src_core_id = logid;
    pmsg_head->msg_size    = APE_MSG_HEAD_SIZE + len;
    pmsg_head->msg_type    = msg_type;

    memcpy((pmsg_head+APE_MSG_HEAD_SIZE), pbuf, len);

    //osp_net_log_proc(pmsg_head);

    free(pmsg_head);
    
    return OSP_OK;
}

OSP_STATUS osp_arm_log_proc(char *pbuf, uint32_t len ,uint32_t logid, uint32_t msg_type)
{    
    uint32_t ul_port = 0;

    if ((NULL == pbuf) || (0 == len))
    {
        return OSP_ERROR;
    }

    switch (msg_type)
    {
        case OSP_BIN_LOG:                    
             ul_port = 32768 + 2*logid;
        break;
        case OSP_STR_LOG:
             ul_port = 32768 + 2*logid + 1;
        break;
        default:            
            break;
    }
        
    /*get default cfg from file*/
    //osp_log_mode_get();

    switch(g_ulArmLogMode)
    {
        case 0:
             osp_write_diaglog(pbuf, len, logid, msg_type);
        break;
        case 1:            
             //g_ulArmNetLogRxNum++;
             osp_net_log_proc(pbuf, len, ul_port);
             //g_ulArmNetLogTxNum++;
        break;
        case 2:
             osp_log_print((osp_sw_msg_info_t *)pbuf);/*ape结果输出到屏幕*/
        break;
        default:
            break;
    }
    
    return OSP_OK;
}

OSP_STATUS osp_ape_log_proc(osp_sw_msg_info_t *pMsg)
{
    uint32_t port = 0;

    if (NULL == pMsg)
    {
        return OSP_ERROR;
    }

    port = osp_get_ape_port(pMsg);

    switch(g_ulApeLogMode)
    {
        case 0:
            osp_write_diaglog((char*)pMsg->i8Data, pMsg->u16DataLen, pMsg->u8CoreId, pMsg->u8PktType);
            break;
        case 1:
            osp_net_log_proc((char*)pMsg->i8Data, pMsg->u16DataLen, port);
            break;
        case 2:
            osp_log_print(pMsg);/*ape结果输出到屏幕*/
            break;
        default:
            break;
    }

    return OSP_OK;
}

void osp_platform_log_proc(osp_sw_msg_info_t *pMsg)
{
    uint32_t port   = 0;

    if (NULL == pMsg)
    {
        return;
    }
	
    port = osp_get_ape_port(pMsg);

    switch(g_ucPlatformMode)
    {
        case 0:
             osp_write_diaglog((char*)pMsg->i8Data, pMsg->u16DataLen, pMsg->u8CoreId, pMsg->u8PktType);
        break;
        case 1:
             osp_net_log_proc((char*)pMsg->i8Data, pMsg->u16DataLen, port);
        break;
        case 2:
             osp_log_print(pMsg);/*ape结果输出到屏幕*/
        break;
        default:            
            break;

    }

	return;
}

void osp_log_print(osp_sw_msg_info_t *pMsg)
{    
    uint32_t i = 0;

    if (NULL == pMsg)
    {
        return;
    }

    if(OSP_BIN_LOG == pMsg->u8PktType)
    {
        for (i = 0; i < pMsg->u16DataLen ;i++)
        {
            printf("%02x  ", (uint8_t)pMsg->i8Data[i]);

            if ((i & 0x7) == 0x7)
            {
                printf("\n");
            }
        }
    }
    else
    {
        write(STDOUT_FILENO, (char*)pMsg->i8Data, pMsg->u16DataLen);/*ape结果输出到屏幕*/
    }

    return;
}


bool osp_ip_is_null(char *ip)
{
    if(NULL == ip)
    {
        strcpy((char *)&gst_server_log.ip, "192.168.20.18");
        return true;
    }

    return false;
}

bool osp_path_is_null(char *path)
{
    if(NULL == path)
    {
        strcpy((char *)&gst_server_log.path, "./log/");
        return true;
    }

    return false;
}


int8_t osp_log_mode_init()
{
    int8_t ret      = 0;
    FILE *fp        = NULL;

    if (access(LOG_MODE_PATH, F_OK) != 0)
    {    
        osp_mkdirs("./server/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 
        osp_mkdirs("./log/", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 

        fp = fopen(LOG_MODE_PATH, "w+");
        if (fp < 0)
        {
            UCP_PRINT_ERROR("osp_log_mode_init file open failure  \n");
            return ret;
        }

        memcpy(gst_server_log.ip, "192.168.20.18", 15);
        strcpy((char *)gst_server_log.path, "./log/");
        gst_server_log.ulport = 32768;

        ret = fprintf(fp,"ip:%s\r\nport:%u\napelog:%u\narmlog:%u\nlogpath:%s", \
                      gst_server_log.ip, gst_server_log.ulport, g_ulApeLogMode, g_ulArmLogMode, gst_server_log.path);
        if(ret < 0)
        {
            UCP_PRINT_ERROR("fwrite error ret:%d\n", ret);
            fclose(fp);
            return ret;
        }

        fflush(fp);
        fclose(fp);
    }
    
    return ret;
}

int8_t osp_log_mode_cfg()
{
    int8_t ret         = 0;
    FILE *fp           = NULL;

    if (access("./server", F_OK) != 0)
    {
        osp_mkdirs("./server", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 
    }
    
    fp = fopen(LOG_MODE_PATH, "w+");
    if (fp < 0)
    {
        UCP_PRINT_ERROR("osp_log_mode_cfg file open failure  \n");
        return ret;
    }

    ret = fprintf(fp,"ip:%s\r\nport:%u\napelog:%u\narmlog:%u\nlogpath:%s", \
                      gst_server_log.ip, gst_server_log.ulport, g_ulApeLogMode, g_ulArmLogMode, \
                      gst_server_log.path);
    if(ret < 0)
    {
        UCP_PRINT_ERROR("osp_log_mode_cfg fprintf error ret:%d\n", ret);
        fclose(fp);
        return ret;
    }

    fflush(fp);
    fclose(fp);
    
    return ret;
}


void osp_cfg_default_log_mode()
{

    memset(gst_server_log.ip, 0, 16);
    memset(gst_server_log.path, 0, 128);

    strcpy((char *)gst_server_log.ip, "192.168.20.18");
    strcpy((char *)gst_server_log.path, "./log/");

    gst_server_log.ulport = 32768;
    g_ulApeLogMode          = 0;
    g_ulArmLogMode          = 0;
    
    return;
}


void osp_log_mode_get()
{
    FILE *fp        = NULL;
    char *ip        = NULL;    
    char *path      = NULL;
    char buf[128]   = {0};

    /*配置gst_server_log默认值*/
    osp_cfg_default_log_mode();
    
    fp = fopen(LOG_MODE_PATH, "r");
    if (NULL == fp)
    {
        UCP_PRINT_ERROR("osp_log_mode_get file open failure  \n");
        return;
    }

    while(fgets(buf, 128, fp))
    {
        if(strstr(buf, "ip:"))
        {
            memset(gst_server_log.ip, 0, 16);
            ip = strtok((char *)(buf+3), "\r\n");
            if(false == osp_ip_is_null(ip))
            {
                strcpy((char *)gst_server_log.ip, ip);
            }
            continue;
        }
        if(strstr(buf, "port:"))
        {
            gst_server_log.ulport = (uint32_t)atoi(buf+5);
            //strncpy((char *)&gst_server_log.ulport, buf+5, 2);
            continue;
        }
        if(strstr(buf, "apelog:"))
        {
            g_ulApeLogMode = (uint32_t)(buf[7] - '0');
            continue;
        }
        if(strstr(buf, "armlog:"))
        {            
            g_ulArmLogMode = (uint32_t)(buf[7] - '0');
            continue;
        }
        if(strstr(buf, "logpath:"))
        {        
            memset(gst_server_log.path, 0, 128);
            path = strtok((char *)(buf+8), "\r\n");
            if(false == osp_path_is_null(path))
            {
                strcpy((char *)gst_server_log.path, path);
            }
            continue;
        }
    }

    /*UCP_PRINT_ERROR("ip:%s port:%u g_ulApeLogMode:%u g_ulArmLogMode:%u\n",\
                     gst_server_log.ip,gst_server_log.ulport,\
                     g_ulApeLogMode, g_ulArmLogMode);*/

    fclose(fp);

    return;
}

uint32_t osp_filter_char(char *str, char c)
{
    uint8_t i       = 0;
    uint32_t ulret  = 0;

    while(str[i] != '\0')
    {
        if(str[i] == c)
        {
            ulret = (uint32_t)(str[++i] - '0');
            printf("%d\n", ulret);
            break;
        }
        i++;
    }

    return ulret;
}

void osp_dbg_log_main(osp_sw_msg_info_t        *pMsg)
{
    if (NULL == pMsg)
    {
        return;
    }
        
    switch (pMsg->u8PktType)
    {
        case OSP_STR_LOG:
        case OSP_BIN_LOG:
            osp_ape_log_proc(pMsg);
            break;
        case OSP_PLATFORM_LOG:
            osp_platform_log_proc(pMsg);
            break;
        default:
            break;
    }

    return;
}


void osp_log_init(void)
{
    uint32_t i = 0;
    uint32_t j = 0;

    /*create arm、ape log cfg file*/
    osp_log_mode_init();
    
    /*get default cfg from cfg file*/
    osp_log_mode_get();

    osp_log_msg_create();

    g_OspLogSem = osp_get_init_mem(sizeof(lx_sem_t));
    osp_semsm_create(g_OspLogSem);

    srand(time(NULL));
    log_rand = rand();

    for (i = 0; i < MAX_LOG_CFG_NUM; i++)
    {
        for(j = 0; j< 4; j++)
        {
            log_file_cfg_table[i][j].valied             = 0;
            log_file_cfg_table[i][j].max_file_size_M    = 0;
            log_file_cfg_table[i][j].max_file_num       = 0;
            log_file_cfg_table[i][j].with_time          = 0;
            log_file_cfg_table[i][j].key                = 0;
        }

    }

    osp_base_logid = osp_create_log((char *)gst_server_log.path, MAX_FILE_SIZE, MAX_FILE_NUM, 1);

    return;
}

void osp_log_cfg_reload()
{
    uint32_t i = 0;
    uint32_t j = 0;
    
    for (i = 0; i < MAX_LOG_CFG_NUM; i++)
    {
        for(j = 0; j< 4; j++)
        {
            log_file_cfg_table[i][j].valied             = 1;
            log_file_cfg_table[i][j].key                = 0;
            log_file_cfg_table[i][j].cur_sum_len        = 0;
            log_file_cfg_table[i][j].cur_file_idx       = 0;
            log_file_cfg_table[i][j].file               = NULL;
        }

    }

    return;
}

int32_t osp_fflush_all_logfile(void)
{
    uint32_t i = 0;
    uint32_t j = 0;
    FILE *file;
    uint32_t fd;
    
    for (i = 0; i < MAX_LOG_CFG_NUM; i++)
    {
        for(j=0; j<4; j++)
        {
            file = osp_get_log_file(i, j);
            if (file)
            {
                fflush(file);
                fd = fileno(file);
                fsync(fd);
            }
        }
    }
    return 0;

}

/* 根据最新需求，Log的处理机制改回1.0的状态，在接受回调函数中直接处理 */
#if 1
#define OSP_LOG_MSG_Q_KEY       (0x1011)
#define OSP_LOG_SEND_TYPE       (0xFA)      /* 发送消息时的消息类型 */
int32_t  gint_log_msg_id = -1;

uint8_t osp_log_msg_create(void)
{
    gint_log_msg_id = msgget(OSP_LOG_MSG_Q_KEY, IPC_CREAT);
    if (-1 == gint_log_msg_id)
    {
        UCP_PRINT_ERROR("[osp_log_msg_create]: msgget return error\r\n");
        return 1;
    }
    UCP_PRINT_LOG("[osp_log_msg_create]: gint_log_msg_id = %d\r\n", gint_log_msg_id);
    return 0;
}

int32_t osp_log_msg_get_id(void)
{
    return gint_log_msg_id;
}

int32_t osp_log_msg_send(int32_t i32que_id, uint8_t *pu8msg_add, uint32_t u32msg_size)
{
    int32_t i32_ret = 0;
    osp_log_msg_info_t* plog_msg = NULL;

    if (NULL == pu8msg_add)
    {
        UCP_PRINT_ERROR("[osp_log_msg_send]: buffer addr is NULL!!!\r\n");
        return -1;
    }
    //printf("send: que_id = %d, addr = %p, size = %d\r\n", i32que_id, pu8msg_add, u32msg_size);

    plog_msg = (osp_log_msg_info_t *)pu8msg_add;
    plog_msg->i64msg_type = OSP_LOG_SEND_TYPE;
    i32_ret = msgsnd(i32que_id, pu8msg_add, (u32msg_size - sizeof(int64_t)), IPC_NOWAIT);
    if (0 != i32_ret)
    {
        UCP_PRINT_LOG("[osp_log_msg_send]: msgsnd return err(%d)\r\n", i32_ret);
    }
    return u32msg_size;
}

int32_t osp_log_msg_recv(int32_t i32que_id, uint8_t *pu8msg_add, uint32_t u32max_size)
{
    int32_t i32_ret = 0;
    osp_log_msg_info_t* plog_msg = NULL;

    if (NULL == pu8msg_add)
    {
        UCP_PRINT_ERROR("[osp_log_msg_recv]: buffer addr is NULL!!!\r\n");
        return -1;
    }

    UCP_PRINT_LOG("[osp_log_msg_recv]: i32que_id(%d), size = %d\r\n", i32que_id, u32max_size);

    plog_msg = (osp_log_msg_info_t*)pu8msg_add;
    i32_ret = msgrcv(i32que_id, pu8msg_add, (u32max_size-sizeof(uint64_t)), 0, 0);
    if (-1 == i32_ret)
    {
        UCP_PRINT_LOG("[osp_log_msg_recv]: msgrcv return err(%d) %s\r\n", i32_ret, strerror(errno));
        return -2;
    }
    if (OSP_LOG_SEND_TYPE != plog_msg->i64msg_type)
    {
        UCP_PRINT_ERROR("[osp_log_msg_recv]: msg_type err(%ld)\r\n", plog_msg->i64msg_type);
        return -3;
    }
    return (i32_ret + sizeof(int64_t));
}

int32_t osp_log_msg_proc(uint8_t *pu8msg_add, uint32_t u32msg_size)
{
    MsgTransferHeader_t *pmsg_transfer_header = NULL;
    osp_sw_msg_info_t   *pstsw_msg_info = NULL;

    uint8_t  u8msg_num = 0;
    uint32_t u32msg_type = 0;
    uint32_t u32log_size = 0;
    uint32_t u32log_num  = 0;
    uint32_t u32msg_cur_size = 0;

    if (NULL == pu8msg_add)
    {
        UCP_PRINT_ERROR("[osp_log_msg_proc]: msg_addr is NULL!!!\r\n");
        return -1;
    }

    pmsg_transfer_header = (MsgTransferHeader_t*)pu8msg_add;

    u8msg_num = pmsg_transfer_header->numMsg;
    u32msg_cur_size += 4;  /* msgType */
    //printf("[osp_log_msg_proc]: u8msg_num = %d\r\n", u8msg_num);

    for (uint8_t u8msg_loop = 0; u8msg_loop < u8msg_num; u8msg_loop++)
    {
        u32msg_type = *(uint32_t*)(pu8msg_add+u32msg_cur_size);
        //printf("[osp_log_msg_proc]: u32msg_type = 0x%x\r\n", u32msg_type);

        if (MSG_TRANSFER_LOG_MSG_TYPE == u32msg_type)
        {
            /* Log */
            u32msg_cur_size += 8; /* log_size */
            u32log_size = *(uint32_t*)(pu8msg_add+u32msg_cur_size);
            u32log_num  = u32log_size/SPU_LOG_CLIENT_BUF_SIZE;
            u32msg_cur_size += 4;

            for (uint16_t u16loop = 0; u16loop < u32log_num; u16loop++)
            {
                pstsw_msg_info = (osp_sw_msg_info_t *)(pu8msg_add + u32msg_cur_size + u16loop*SPU_LOG_CLIENT_BUF_SIZE);

                //printf("i8Data = %p, len = %d, coreid = %d, type = %d\r\n", pstsw_msg_info->i8Data, pstsw_msg_info->u16DataLen, pstsw_msg_info->u8CoreId, pstsw_msg_info->u8PktType);
                //osp_write_diaglog((char*)pstsw_msg_info->i8Data, pstsw_msg_info->u16DataLen, pstsw_msg_info->u8CoreId, pstsw_msg_info->u8PktType);
                osp_dbg_log_main(pstsw_msg_info);
            }
            u32msg_cur_size += u32log_size;
        }
        else if (MSG_TRANSFER_SHELL_MSG_TYPE == u32msg_type)
        {
            UCP_PRINT_LOG("SHELL \r\n");
            /* Shell */
            u32msg_cur_size += 8; /* log_size */
            u32log_size = *(uint32_t*)(pu8msg_add+u32msg_cur_size);
            u32msg_cur_size += 4;
            u32msg_cur_size += u32log_size;
        }
        else
        {
            UCP_PRINT_LOG("OAM \r\n");
            /* OAM */
            u32msg_cur_size += 8; /* log_size */
            u32log_size = *(uint32_t*)(pu8msg_add+u32msg_cur_size);
            u32msg_cur_size += 4;
            u32msg_cur_size += u32log_size;
        }
    }
    return 0;
}

uint32_t rx_callback_oam(const char* buf,uint32_t payloadSize)
{
    osp_log_msg_info_t stosp_log_msg;
    int32_t i32log_que_id = osp_log_msg_get_id();

    memset(&stosp_log_msg, 0, sizeof(stosp_log_msg));
    stosp_log_msg.pu8msg_addr = (uint8_t *)buf;
    stosp_log_msg.u32msg_size = payloadSize;

    //UCP_PRINT_LOG("oam recv: buf = %p, size = %d\r\n", buf, payloadSize);

    osp_log_msg_send(i32log_que_id, (uint8_t*)&stosp_log_msg, sizeof(stosp_log_msg));

    return payloadSize;
}


uint64_t osp_oam_msg_proc_task(void)
{
    osp_log_msg_info_t stosp_log_msg;
    int32_t i32_msg_id = osp_log_msg_get_id();
    static uint32_t su32LogCnt = 0;

    ++su32LogCnt;
    //printf("LogTask Enter >>> %d\r\n", su32LogCnt);
    //while(1)
    //{
        memset(&stosp_log_msg, 0, sizeof(stosp_log_msg));
        if (0 > osp_log_msg_recv(i32_msg_id, (uint8_t*)&stosp_log_msg, sizeof(stosp_log_msg)))
        {
            UCP_PRINT_ERROR("[osp_oam_msg_proc_task]: osp_log_msg_recv return err\r\n");
            //continue;
            return OSP_ERROR;
        }
        UCP_PRINT_LOG("task: addr = %p ,size = %d\r\n", stosp_log_msg.pu8msg_addr, stosp_log_msg.u32msg_size);
        osp_log_msg_proc(stosp_log_msg.pu8msg_addr, stosp_log_msg.u32msg_size);
    //}
    return OSP_OK;
}
#endif

int32_t osp_create_oam_msg_task(uint8_t cpu, uint8_t pri)
{
    OSP_TASKMSG_REG task_reg_tabl;

    memset(&task_reg_tabl, 0, sizeof(task_reg_tabl));
    task_reg_tabl.TaskId = OspDbgLog;
    task_reg_tabl.TaskPri = RT_NOMSG_PRI(pri);
    task_reg_tabl.Init    = NULL;
    task_reg_tabl.MainLoop = (OSP_FUNCPTR)osp_oam_msg_proc_task;
    task_reg_tabl.Cpu = cpu;

    return osp_regtask(&task_reg_tabl);
}


#if 0
uint32_t rx_callback_oam(const char* buf,uint32_t payloadSize)
{
    MsgTransferHeader_t *pmsg_transfer_header = NULL;
    osp_sw_msg_info_t   *pstsw_msg_info = NULL;

    uint8_t  u8msg_num = 0;
    uint32_t u32msg_type = 0;
    uint32_t u32log_size = 0;
    uint32_t u32log_num  = 0;
    uint32_t u32msg_cur_size = 0;

    if (NULL == buf)
    {
        UCP_PRINT_ERROR("[osp_log_msg_proc]: msg_addr is NULL!!!\r\n");
        return -1;
    }

    pmsg_transfer_header = (MsgTransferHeader_t*)buf;

    u8msg_num = pmsg_transfer_header->numMsg;
    u32msg_cur_size += 4;  /* msgType */
    //printf("[osp_log_msg_proc]: u8msg_num = %d\r\n", u8msg_num);

    for (uint8_t u8msg_loop = 0; u8msg_loop < u8msg_num; u8msg_loop++)
    {
        u32msg_type = *(uint32_t*)(buf+u32msg_cur_size);
        //printf("[osp_log_msg_proc]: u32msg_type = 0x%x\r\n", u32msg_type);

        if (MSG_TRANSFER_LOG_MSG_TYPE == u32msg_type)
        {
            /* Log */
            u32msg_cur_size += 8; /* log_size */
            u32log_size = *(uint32_t*)(buf+u32msg_cur_size);
            u32log_num  = u32log_size/SPU_LOG_CLIENT_BUF_SIZE;
            u32msg_cur_size += 4;

            for (uint16_t u16loop = 0; u16loop < u32log_num; u16loop++)
            {
                pstsw_msg_info = (osp_sw_msg_info_t *)(buf + u32msg_cur_size + u16loop*SPU_LOG_CLIENT_BUF_SIZE);

                //printf("i8Data = %p, len = %d, coreid = %d, type = %d\r\n", pstsw_msg_info->i8Data, pstsw_msg_info->u16DataLen, pstsw_msg_info->u8CoreId, pstsw_msg_info->u8PktType);
                //osp_write_diaglog((char*)pstsw_msg_info->i8Data, pstsw_msg_info->u16DataLen, pstsw_msg_info->u8CoreId, pstsw_msg_info->u8PktType);
                osp_dbg_log_main(pstsw_msg_info);
            }
            u32msg_cur_size += u32log_size;
        }
        else if (MSG_TRANSFER_SHELL_MSG_TYPE == u32msg_type)
        {
            UCP_PRINT_LOG("SHELL \r\n");
            /* Shell */
            u32msg_cur_size += 8; /* log_size */
            u32log_size = *(uint32_t*)(buf+u32msg_cur_size);
            u32msg_cur_size += 4;
            u32msg_cur_size += u32log_size;
        }
        else
        {
            UCP_PRINT_LOG("OAM \r\n");
            /* OAM */
            u32msg_cur_size += 8; /* log_size */
            u32log_size = *(uint32_t*)(buf+u32msg_cur_size);
            u32msg_cur_size += 4;
            u32msg_cur_size += u32log_size;
        }
    }
    return u32msg_cur_size;
}
#endif

