
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <ctype.h>
#include <unistd.h>
#include <stdarg.h>
#include <sys/mman.h>
#include "osp.h"
#include "ospShell.h"
#include "ospDbg.h"
#include "ospSoftQue.h"
#include "ospBuf.h"
#include "ospTimer.h"
#include "ospHeap.h"
#include "ospTypes.h"
#include "ucp_printf.h"
#include "ospHeap.h"
#include "ospDump.h"
#include "ospSwQueue.h"
#include "pet_sm_mgt.h"
#include "msg_transfer_layer.h"
#include "ospHeartbeat.h"
#include "ospVersion.h"


#define MAX_CMD_LEN           (150)        /*the max length of a shell command */
#define MAX_CMD_NUM            128

extern uint32_t g_ulApeLogMode;      /*0: ape log日志写入文件 1: 网口输出ape log 2:ape log日志shell打印输出*/
extern uint32_t g_ulArmLogMode;      /*0: arm log日志写入文件 1: 网口输出arm log 2:arm log日志shell打印输出*/
extern uint8_t  g_ucPlatformMode;    /*0: platform log日志写入文件 1: 网口输出platform log 2:platform log日志shell打印输出*/

extern OSP_CMD_RTN ospCmdRtnTbl[];
extern int32_t SHELL_CMD_NUM;

/*function prototype */
extern void osp_set_prompt();

uint8_t guc_oam           = 0;
uint8_t guc_ape_id        = 0;
uint8_t gac_cmd[32]       = {0};
uint8_t guc_print_level   = 0x4;
uint32_t gul_arg[128]       = {0};

Osp_Ape_Send_Count ga_ape_send_count[10];
extern uint8_t g_ucIsEcho;
extern int32_t g_ProcessId;
extern uint8_t    g_time_now[128];
extern Osp_Server_Head gst_server_log;
extern int32_t osp_base_logid;
extern void *gpsw_que_share_mem;

struct termios saveterm;

OSP_CMD_RTN ospApeCmdRtnTbl[MAX_CMD_NUM];
OSP_CMD_RTN *ospCmdRtnTblExt   = NULL;
lx_sem_t *ospCmdInsertSem      = NULL;
lx_sem_t *ospApeCmdInsertSem   = NULL;

void osp_mem_show(char *addr , uint32_t ulLen);

void help(void);
OSP_CMD_RTN ospCmdRtnTbl[MAX_CMD_NUM] = 
{
    {"help", (OSP_FUNCPTR)help, NULL, },
    {"?", (OSP_FUNCPTR)help, NULL, },
    {"i", (OSP_FUNCPTR)osp_show_task_info, NULL,"show alltask info", 0},
    {"oam", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_set_oam, "set arm oam level", 1},
    {"phym", (OSP_FUNCPTR)osp_shell_mem_wrapper, (OSP_FUNCPTR)osp_display_phy_mem, "show phy mempry info", 2},
    //{"c", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_show_tsk_diag_cnt, "show Task Diag Cnt", 1},
    //{"sw", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_show_swqueue_info, "show arm print level", 0},
    {"net", (OSP_FUNCPTR)osp_show_udp, NULL, "show net info", 0},
    //{"sw", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_show_swqueue_info, "show arm print level", 0},
    {"level", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_set_print_level, "set arm print level", 1},
    {"slevel", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_show_print_level, "show arm print level", 0},
    {"dump", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_dump_proc, "dump ddr mem", 4},
    {"dumpdm", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_dump_dm_by_apcid, "dump dm info to bin by apcid", 4},
    {"apcdm", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_show_dm_by_apcid, "show dm info by apcid", 3},
    {"dl", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_show_queue_dl_info, "show dl queue info", 0},
    {"ul", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_show_queue_ul_info, "show ul queue info", 0},
    {"apeid", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_get_ape_id, "get ape id", 1},
    {"apelog", (OSP_FUNCPTR)osp_shell_wrapper,(OSP_FUNCPTR)osp_set_ape_log_mode,  "0: ape log write file 1: ape log out to net 2:ape log to shell", 1},
    {"armlog", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_set_arm_log_mode, "0: arm log write file 1: arm log out to net 2:arm log to shell", 1},
    {"plog", (OSP_FUNCPTR)osp_shell_wrapper,(OSP_FUNCPTR)osp_set_platform_log_mode,  "0: platform log write file 1: platform log out to net 2:platform log to shell", 1},
    {"server", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_server_cfg, "server ip port", 2},
    {"ss", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_server_cfg_show, "show server cfg", 0},
    {"logpath", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_log_path_cfg, "cfg log path", 1},
    {"relog", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_log_mode_get,"reload log cfg", 0},
    //{"tfu", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_get_tfu_location_info, "get tfu location", 0},
    //{"clock_info", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_get_clock_tracking_state, "get clock tracking state", 0},
    //{"ret_clock", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_reset_clock_module, "reset clock module", 0},
    //{"set_clock", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_set_clk_mode, "set clock module", 1},
    {"recmd_ape", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_reget_ape_cmd, "get ape cmd again", 0},
    {"intr_ape", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_ape_csu_int_cnt, "show intr info", 0},
    {"hb", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)get_heartbeat_status, "test heartbeat", 0},
    {"apecmd", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_ape_cmd_show, "show ape register cmd", 0},
    {"armcmd", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_arm_cmd_show, "show arm register cmd", 0},
    {"version", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_soft_version_show, "show soft version info", 0},
    //{"level_ape", (OSP_FUNCPTR)osp_shell_wrapper,(OSP_FUNCPTR)osp_ape_set_log_level, "set ape log level", 1},
    //{"csu_stop_ape", (OSP_FUNCPTR)osp_shell_wrapper,(OSP_FUNCPTR)osp_ape_csu_stop_cfg, "set csu start or stop", 2},
    //{"i_ape", (OSP_FUNCPTR)osp_shell_wrapper, (OSP_FUNCPTR)osp_show_ape_taskinfo, "show ape task info", 0},
};


int32_t  SHELL_CMD_NUM = OSP_NELEMENTS(ospCmdRtnTbl);
int32_t  SHELL_CMD_NUM_EXT     = 0;
uint32_t g_u32ApeShellCmdNum = 0;

#define KEY_BACKSPACE    '\b'    // back space
#define KEY_BACKSPACE1    127    // back space
#define KEY_ENTER        '\x0A'    // enter

#define MAX_CMD_HISTORY 32

#define MAX_EXT_CMD_NUM MAX_CMD_NUM

typedef enum
{
    WKS_WAIT,
    WKS_RECV1B,
    WKS_UDLR,
    WKS_DEL,
}T_WaitKeyState;

static char szPrompt[] = {"-> "};

static T_WaitKeyState waitKeyState = WKS_WAIT;
static char szCmdHistory[MAX_CMD_HISTORY][MAX_CMD_LEN];
static char szCmdNow[MAX_CMD_LEN] = {0};

static uint32_t nCmdIndex = 0;
static uint32_t nCmdCursor = 0;
static uint32_t nCmdInputCount = 0;
static uint32_t nCmdInputCursor = 0;

int32_t cmdMatched = 0;
char cmdMatchBuf[OSP_NELEMENTS(ospCmdRtnTbl)][MAX_CMD_LEN + 10] = {0};
char cmdShowBuf[MAX_CMD_LEN*OSP_NELEMENTS(ospCmdRtnTbl)] = {0};

bool gEscOn = false;



int32_t nCmdField;
int32_t maxCmdField = 10;
char **arg = NULL;

void osp_mem_show(char *addr , uint32_t ulLen)
{
#if 0
    int32_t i;

    if (NULL == addr)
    {
        return;
    }
    
    if (ulLen > 65535)
    {
        return;
    }
        
    for (i = 0; i < ulLen; i++)
    {
        if ((i & 0x3) == 0)
        {
            UCP_PRINT_SHELL("0x%08x: \t", addr+i);
        }

        UCP_PRINT_SHELL("%08x\t", addr[i]);
        
        if ((i & 0x3) == 0x3)
        {
            UCP_PRINT_SHELL("\n");
        }
    }
#endif
    return;
}

void help(void)
{
    int32_t i;
    char buf[4096] = {0};
    int32_t len = 0;
    
    len += sprintf(buf+len, "%-16s%s\n", "cmd", "descption");
    for (i = 0; i < MAX_CMD_NUM; i++)
    {
        if (ospCmdRtnTbl[i].cmd[0] != 0)
        {
            len += sprintf(buf + len, "%-16s%s\n", ospCmdRtnTbl[i].cmd, ospCmdRtnTbl[i].descption);
                
        }
    }
    for (i = 0; i < MAX_CMD_NUM; i++)
    {
        if (ospCmdRtnTblExt[i].cmd[0] != 0)
        {
            len += sprintf(buf + len, "%-16s%s\n", ospCmdRtnTblExt[i].cmd, ospCmdRtnTblExt[i].descption);
                
        }
    }

    for (i = 0; i < MAX_CMD_NUM; i++)
    {
        if (ospApeCmdRtnTbl[i].cmd[0] != 0)
        {
            if (strcmp(ospApeCmdRtnTbl[i].cmd, "ver_spu") != 0) {
                len += sprintf(buf + len, "%-16s%s\n", ospApeCmdRtnTbl[i].cmd, ospApeCmdRtnTbl[i].descption);
            }
        }
    }
        
    UCP_PRINT_SHELL("%s\n", buf);

    osp_net_shell_out((char *)buf, len);

    return;
}


/*
 * osp_set_outstr - print string to console
 * input:
 *    out : output string
 * return
 *    none
 */

void osp_set_outstr(char *out)
{
    UCP_PRINT_SHELL("%s", out);
}

/*
 * osp_set_prompt - set prompt string to console
 * input:
 *    none
 * return
 *    none
 */

void osp_set_prompt()
{
    UCP_PRINT_SHELL("%s", szPrompt);
}
static int64_t argval[10] = {0};
static char argchar[10][32] = {0};
static char shellOut[64] = {0};

int32_t osp_str_is_digit(char *buf)
{
    int32_t i;
    int32_t size = strlen(buf);
    for (i = 0; i < size; i++)
    {
        if (0 == isdigit(buf[i]))
            return 0;
    }

    return 1;
}
int32_t osp_shell_symo(char **arg, int32_t len)
{
    int32_t i;
    OSP_FUNCPTR func;
    //INT32 size;

    uint64_t func_ret;
    
    for (i = 0; i < len; i++)
    {
                    
        if (((arg[i][0] == '0') && ((arg[i][1] == 'x') || (arg[i][1] == 'X'))) && osp_str_is_digit(arg[i]))
        {
            
            argval[i] = strtoul(arg[i], (char **)NULL, 16);
        }
        else if (isdigit(arg[i][0]) && osp_str_is_digit(arg[i]))
        {
            argval[i] = strtoul(arg[i], (char **)NULL, 10);
        }
        else
        {
            strcpy(argchar[i], arg[i]);
            argval[i] = (int64_t)argchar[i];
        }
    }

    func = osp_find_sym(argchar[0]);
        
    if (func)
    {
        func_ret = func(argval[1], argval[2], argval[3], argval[4], 
            argval[5], argval[6], argval[7], argval[8], argval[9]);
        sprintf(shellOut, "value = %p\r\n", (void *)func_ret);
        osp_set_outstr(shellOut);
        return 0;
    }

    return -1;

}

int32_t osp_shell_mem_wrapper(char **arg, int32_t len, OSP_FUNCPTR func)
{  
    int32_t i;
    int32_t ret;

    for (i = 0; i < len; i++)
    {
        if ((arg[i][0] == '0') && ((arg[i][1] == 'x') || (arg[i][1] == 'X')))
        {
            argval[i] = strtoul(arg[i], (char **)NULL, 16);
        }
        else if (isdigit(arg[i][0]))
        {
            argval[i] = strtoul(arg[i], (char **)NULL, 10);
        }

        else
        {
            strcpy(argchar[i], arg[i]);
            argval[i] = (uint64_t)osp_find_sym(&argchar[i][0]);
        }
    }

        

    ret = func(argval[0], argval[1], argval[2], argval[3], 
        argval[4], argval[5], argval[6], argval[7], argval[8]);;
    return ret;

}

int32_t osp_shell_wrapper(char **arg, int32_t len, OSP_FUNCPTR func)
{
    int32_t i;
    int32_t ret;
    
    memset(argchar, 0, sizeof(argchar));
    for (i = 0; i < len; i++)
    {
        if ((arg[i][0] == '"'))
        {
            strncpy(argchar[i], &arg[i][1],strlen(arg[i])-2);
            argval[i] = (int64_t)argchar[i];
        }
        else if ((arg[i][0] == '0') && ((arg[i][1] == 'x') || (arg[i][1] == 'X')))
        {
            argval[i] = strtoul(arg[i], (char **)NULL, 16);
        }
        else if (isdigit(arg[i][0]))
        {
            argval[i] = strtoul(arg[i], (char **)NULL, 10);
        }
        else
        {
            strcpy(argchar[i], arg[i]);
            argval[i] = (int64_t)argchar[i];
        }
    }
    
    ret = func(argval[0], argval[1], argval[2], argval[3], argval[4], 
        argval[5], argval[6], argval[7], argval[8], argval[9]);

    return ret;
}

uint32_t osp_ape_shell_wrapper(char **arg, uint32_t len, OSP_FUNCPTR func)
{
    uint32_t i       = 0;
    uint32_t ullen   = 0;
    char aCmd[128]   = {0};

    memset(argchar, 0, sizeof(argchar));
    for (i = 0; i < len; i++)
    {
        ullen = strlen(arg[i]);
        if(ullen > 12)
        {
            UCP_PRINT_SHELL("len should less 12\n" );
            return OSP_ERROR;
        }
        
        if ((arg[i][0] == '"'))
        {
            strncpy(argchar[i], &arg[i][1],ullen-2);
        }
        else
        {
            strcpy(argchar[i], arg[i]);
        }
        
    }

    sprintf(aCmd, "%s %s %s %s %s %s %s %s %s %s %s %s", gac_cmd, argchar[0], argchar[1], \
                                          argchar[2], argchar[3], argchar[4], \
                                          argchar[5], argchar[6], argchar[7], \
                                          argchar[8], argchar[9], argchar[10]);

    UCP_PRINT_LOG("osp_ape_shell_wrapper gac_cmd:%s aCmd:%s\n", gac_cmd, aCmd);
    osp_ape_msg_send((char *)aCmd); 
    
    return 0;
}


int32_t osp_shell_str_wrapper(char **arg, int32_t len, OSP_FUNCPTR func)
{
    int32_t i;
    int32_t ret;
    
    memset(argchar, 0, sizeof(argchar));
    for (i = 0; i < len; i++)
    {        
        strcpy(argchar[i], arg[i]);
        argval[i] = (int64_t)argchar[i];  
        UCP_PRINT_SHELL("osp_shell_str_wrapper argval[%d] = %ld ; argchar[%d] = %s ", i, argval[i], i, argchar[i]);
    }
    
    ret = func(argval[0], argval[1], argval[2], argval[3], argval[4], 
        argval[5], argval[6], argval[7], argval[8], argval[9]);

    return ret;
}

/*
 * getFullCmdMatch - get matched command name list
 * input:
 *    pCmd : the prefix of a command
 * return
 *    none
 */

int32_t osp_get_full_cmd_match(char*pCmd)
{
    int32_t index;
    char*pMatch;

    for (index = 0; index < OSP_NELEMENTS(ospCmdRtnTbl); index++)
    {
        pMatch = strstr(ospCmdRtnTbl[index].cmd, pCmd);
        if ((pMatch != NULL) && (pMatch == ospCmdRtnTbl[index].cmd))
        {
            strcpy(cmdMatchBuf[cmdMatched], ospCmdRtnTbl[index].cmd);
            cmdMatched++;
        }
    }
    return cmdMatched;
}


/*
 * osp_getcmdarg - split command to params,then save to array arg
 * input:
 *    cmd : pointer to command
 * return
 *    params number
 */

int32_t osp_getcmdarg(char *cmd)
{
    char seps[]=" ,\t\n";
    char *token;
    char **p;

    nCmdField = 0;

    token = strtok(cmd, seps);
    
    while (token != NULL)
    {   
        if (nCmdField >= maxCmdField)
        {
            maxCmdField *= 2;
            p = (char **)realloc(arg, maxCmdField * sizeof(arg[0]));
            if (p == NULL)
                return -1;
            else
                arg = p;
        }
        arg[nCmdField] = token;
        token = strtok(NULL, seps);

        nCmdField++;
    }

    return nCmdField;
}


/*
 * osp_execcmd - execute command
 * input:
 *    none
 * return
 *    OSP_OK,or
 *    OSP_ERROR(fail)
 */

int32_t osp_execcmd(void)
{
    int32_t i;
    int32_t ret = 0;

    if (nCmdField > 0)
    {
        /*本地命令数组*/
        for (i = 0; i < SHELL_CMD_NUM; i++)
        {
            if (strcmp(ospCmdRtnTbl[i].cmd, arg[0]) == 0)
            {   
                if (ospCmdRtnTbl[i].argnum != nCmdField-1)
                {
                    UCP_PRINT_ERROR("input wrong argnum should be %d\n", ospCmdRtnTbl[i].argnum);                    
                    return OSP_ERROR;
                }

                ret = (*ospCmdRtnTbl[i].wrapper)(&arg[1], nCmdField-1, ospCmdRtnTbl[i].routine);
                
                return (OSP_OK);
            }
        }

        /*arm侧动态注册命令*/
        for (i = 0; i < SHELL_CMD_NUM_EXT; i++)
        {
            if (strcmp(ospCmdRtnTblExt[i].cmd, arg[0]) == 0)
            {
                if (ospCmdRtnTblExt[i].argnum != nCmdField-1)
                {
                    UCP_PRINT_ERROR("arm cmd:%s input wrong argnum should be %d\n", ospCmdRtnTblExt[i].cmd, ospCmdRtnTblExt[i].argnum);
                    return OSP_ERROR;
                }
                
                ret = (*ospCmdRtnTblExt[i].wrapper)(&arg[1], nCmdField - 1, ospCmdRtnTblExt[i].routine);

                return (OSP_OK);
            }
        }

        /*ape侧动态注册命令*/
        for (i = 0; i < g_u32ApeShellCmdNum; i++)
        {
            if (strcmp(ospApeCmdRtnTbl[i].cmd, arg[0]) == 0)
            {
                if (ospApeCmdRtnTbl[i].argnum != nCmdField-1)
                {
                    UCP_PRINT_ERROR("ape cmd:%s input wrong argnum should be %d\n", ospApeCmdRtnTbl[i].cmd, ospApeCmdRtnTbl[i].argnum);
                    return OSP_ERROR;
                }
                            
                memcpy(gac_cmd, ospApeCmdRtnTbl[i].cmd, strlen(ospApeCmdRtnTbl[i].cmd));
                ret = (*ospApeCmdRtnTbl[i].wrapper)(&arg[1], nCmdField-1, ospApeCmdRtnTbl[i].routine);
                memset(gac_cmd, 0, sizeof(gac_cmd));
                        
                return (OSP_OK);
            }
        }
        ret = osp_shell_symo(&arg[0], nCmdField);
        return ret;
    }
    return (OSP_ERROR);
}

/*
 * osp_shell_writebs - delete a character of command line
 * input:
 *    none
 * return
 *    none
 */

void osp_shell_writebs()
{
    char szTemp[3];
    szTemp[0] = '\b';
    szTemp[1] = ' ';
    szTemp[2] = '\b';
    write(STDOUT_FILENO, szTemp, 3);
}

/*
 * osp_shell_deal_input - handle keypress
 * input:
 *    input: input key code
 * return
 *    none
 */

void osp_shell_deal_input(char input)
{
    if (nCmdInputCount == MAX_CMD_LEN)
        return;

    if (nCmdInputCursor < nCmdInputCount)
    {
        char szTemp[MAX_CMD_LEN] = {0};
        char *pCmd = szCmdNow;
        int32_t nBackCount = nCmdInputCount - nCmdInputCursor;
        szTemp[0] = input;
        memcpy(&szTemp[1], &pCmd[nCmdInputCursor], nBackCount);
        write(STDOUT_FILENO, szTemp, nBackCount + 1);
        memcpy(&pCmd[nCmdInputCursor], &szTemp, nBackCount + 1);

        memset(szTemp, '\b', nBackCount);
        write(STDOUT_FILENO, szTemp, nBackCount);
    }
    else
    {
        write(STDOUT_FILENO, &input, 1);
        szCmdNow[nCmdInputCount] = input;
    }

    nCmdInputCursor++;
    nCmdInputCount++;
}

/*
 * osp_shell_deal_backspace - handle key 'Backspace'
 * input:
 *    none
 * return
 *    none
 */

void osp_shell_deal_backspace()
{
    if (nCmdInputCursor > 0)
    {
        if (nCmdInputCursor == nCmdInputCount) //cursor at the end
            osp_shell_writebs();
        else
        {
            char szTemp[MAX_CMD_LEN] = {0};
            char*pCmd = szCmdNow;
            int32_t nBackCount = nCmdInputCount - nCmdInputCursor;
            szTemp[0] = '\b';
            memcpy(&szTemp[1], &pCmd[nCmdInputCursor], nBackCount);
            szTemp[nBackCount+1] = ' ';
            write(STDOUT_FILENO, szTemp, nBackCount + 2);
            memcpy(&pCmd[nCmdInputCursor - 1], &szTemp[1], nBackCount);

            memset(szTemp, '\b', nBackCount + 1);
            write(STDOUT_FILENO, szTemp, nBackCount + 1);
        }
        nCmdInputCount--;
        nCmdInputCursor--;
    }
}

/*
 * osp_shell_deal_delete - handle key 'Delete'
 * input:
 *    none
 * return
 *    none
 */

void osp_shell_deal_delete()
{
    if (nCmdInputCursor < nCmdInputCount)
    {
        char szTemp[MAX_CMD_LEN] = {0};
        char *pCmd = szCmdNow;

        int32_t nBackCount = nCmdInputCount - nCmdInputCursor - 1;
        memcpy(szTemp, &pCmd[nCmdInputCursor + 1], nBackCount);
        szTemp[nBackCount] = ' ';
        write(STDOUT_FILENO, szTemp, nBackCount + 1);
        memcpy(&pCmd[nCmdInputCursor], szTemp, nBackCount);

        memset(szTemp, '\b', nBackCount + 1);
        write(STDOUT_FILENO, szTemp, nBackCount + 1);
        nCmdInputCount--;
    }
}

/*
 * osp_shell_deal_doubleesc - clear command line
 * input:
 *    none
 * return
 *    none
 */

void osp_shell_deal_doubleesc()
{
    if (nCmdInputCount > 0)
    {
        char *pCmd = szCmdNow;

        //move to end
        while (nCmdInputCursor < nCmdInputCount)
        {
            write(STDOUT_FILENO, &pCmd[nCmdInputCursor], 1);
            nCmdInputCursor++;
        }

        //clear all inputs
        int32_t i = 0;
        for (i = 0; i < nCmdInputCount; i++)
            osp_shell_writebs();
        nCmdInputCount = 0;
        nCmdInputCursor = 0;
    }
}

/*
 * osp_shell_deal_upkey - handle key 'up'
 * input:
 *    none
 * return
 *    none
 */

void osp_shell_deal_upkey()
{
    if (nCmdCursor == 0)
        return;

    nCmdCursor --;

    //clear all inputs
    osp_shell_deal_doubleesc();

    char *pCmdHistory = &szCmdHistory[nCmdCursor][0];
    memcpy(szCmdNow, pCmdHistory, MAX_CMD_LEN);
    nCmdInputCount = strlen(szCmdNow);
    nCmdInputCursor = nCmdInputCount;
    write(STDOUT_FILENO, szCmdNow, nCmdInputCount);
}

/*
 * osp_shell_deal_downkey - handle key 'down'
 * input:
 *    none
 * return
 *    none
 */

void osp_shell_deal_downkey()
{
    if (nCmdCursor >= (nCmdIndex-1)) return;
    nCmdCursor ++;

    //clear all inputs
    osp_shell_deal_doubleesc();

    char*pCmdHistory = &szCmdHistory[nCmdCursor][0];
    memcpy(szCmdNow, pCmdHistory, MAX_CMD_LEN);
    nCmdInputCount = strlen(szCmdNow);
    nCmdInputCursor = nCmdInputCount;
    write(STDOUT_FILENO, szCmdNow, nCmdInputCount);

}

/*
 * osp_shell_deal_leftkey - handle key 'left'
 * input:
 *    none
 * return
 *    none
 */

void osp_shell_deal_leftkey()
{
    if (nCmdInputCursor > 0)
    {
        char c = '\b';
        write(STDOUT_FILENO, &c, 1);
        nCmdInputCursor--;
    }
}

/*
 * osp_shell_deal_rightkey - handle key 'right'
 * input:
 *    none
 * return
 *    none
 */

void osp_shell_deal_rightkey()
{
    if (nCmdInputCursor < nCmdInputCount)
    {
        char *pCmd = szCmdNow;
        char c = pCmd[nCmdInputCursor];
        write(STDOUT_FILENO, &c, 1);
        nCmdInputCursor++;
    }
}

/*
 * osp_shell_deal_enter - handle key 'Enter'
 * input:
 *    none
 * return
 *    none
 */

void osp_shell_deal_enter()
{
    szCmdNow[nCmdInputCount] = '\0';
    char szTemp[] = {"\r\n"};
    write(STDOUT_FILENO, szTemp, strlen(szTemp));
    nCmdInputCount = 0;
    nCmdInputCursor = 0;

    if (strlen(szCmdNow) == 0)
        return;

    if (nCmdIndex == MAX_CMD_HISTORY)
    {
        char szTempCmd[MAX_CMD_HISTORY][MAX_CMD_LEN];
        memcpy(szTempCmd, &szCmdHistory[1][0], MAX_CMD_LEN * (MAX_CMD_HISTORY - 1));
        memcpy(szCmdHistory, szTempCmd, MAX_CMD_LEN * (MAX_CMD_HISTORY - 1));
        nCmdIndex = MAX_CMD_HISTORY - 1;
        nCmdCursor = nCmdIndex;
    }

    memcpy(szCmdHistory[nCmdIndex], szCmdNow, MAX_CMD_LEN);

    nCmdIndex++;
    nCmdCursor = nCmdIndex;
}


/*
 * osp_shell_deal_tab - handle key 'tab'
 * input:
 *   none
 * return
 *   none
 */

void osp_shell_deal_tab()
{
    int32_t matchNum;
    int32_t matchIndex;
    int32_t lenDiff;
    int32_t  cmdBufLen = 0;
    char cmdPre[MAX_CMD_LEN] = {0};

    cmdBufLen = nCmdInputCursor;
    szCmdNow[cmdBufLen] = '\0';

    strcpy(cmdPre, szCmdNow);
    matchNum = osp_get_full_cmd_match(cmdPre);

    memset(cmdShowBuf, 0, sizeof(cmdShowBuf));
    if (matchNum == 1)
    {
        strcpy(cmdShowBuf, cmdMatchBuf[0]);

        lenDiff = strlen(cmdShowBuf) - strlen(cmdPre);
        write(STDOUT_FILENO, &cmdShowBuf[cmdBufLen], lenDiff);

        strcpy(szCmdNow, cmdShowBuf);
        nCmdInputCursor += lenDiff;
        nCmdInputCount += lenDiff;
    }
    else
    {
        strcat(cmdShowBuf, "\r\n");

        for (matchIndex = 0; matchIndex < matchNum; matchIndex++)
        {
            strcat(cmdShowBuf, cmdMatchBuf[matchIndex]);
            strcat(cmdShowBuf, "    ");
            if ((matchIndex + 1) % 4 == 0)
            {
                strcat(cmdShowBuf, "\r\n");
            }
        }
        strcat(cmdShowBuf, "\r\n");
        strcat(cmdShowBuf, szPrompt);
        strcat(cmdShowBuf, szCmdNow);
        osp_set_outstr(cmdShowBuf);
    }
    memset(cmdMatchBuf, 0, sizeof(cmdMatchBuf));
    cmdMatched = 0;
}

/*
 * osp_shell_get_line - read whole command line string
 * input:
 *   none
 * return
 *   none
 */

void osp_shell_get_line()
{
    bool bGetEnter = false;
    while (true)
    {
        char input;
        input = getchar();

        switch (waitKeyState)
        {
            case WKS_WAIT :
                if (isprint(input))
                    osp_shell_deal_input(input);
                else
                {
                    if (input == '\t')
                    {
                        osp_shell_deal_tab();
                    }
                    else if (input == KEY_BACKSPACE)
                    {
                        osp_shell_deal_backspace();
                    }
                    else if (input == KEY_ENTER)
                    {
                        osp_shell_deal_enter();
                        bGetEnter = true;
                    }
                    else if (input == '\x1b')
                        waitKeyState = WKS_RECV1B;
                    else
                        waitKeyState = WKS_WAIT;
                }
                break;

            case WKS_RECV1B:
                if (input == '\x1b') 
                {
                    osp_shell_deal_doubleesc();
                    waitKeyState = WKS_RECV1B;
                }
                else if (input == '[')   //maybe "up/down/left/right"
                {
                    waitKeyState = WKS_UDLR;
                }
                else  //after pressing 'ESC'
                {
                    if (isprint(input))
                        osp_shell_deal_input(input);
                    waitKeyState = WKS_WAIT;
                }
                break;

            case WKS_UDLR:
                if (input == 'A')          //up
                    osp_shell_deal_upkey();
                else if (input == 'B')     //down
                    osp_shell_deal_downkey();
                else if (input == 'D')     //left
                    osp_shell_deal_leftkey();
                else if (input == 'C')     //right
                    osp_shell_deal_rightkey();
                else if (input == 51)      //maybe key 'delete'
                {
                    waitKeyState = WKS_DEL;
                    break;
                }
                else
                {
                    if (isprint(input))
                        osp_shell_deal_input(input);
                }
                waitKeyState = WKS_WAIT;
                break;

            case WKS_DEL:
                if (input == 126)
                    osp_shell_deal_delete();
                else
                {
                    if (isprint(input))
                        osp_shell_deal_input(input);
                }
                waitKeyState = WKS_WAIT;
                break;

            default:
                break;
        }

        if (bGetEnter)
        {
            break;
        }
    }
}

int32_t osp_insert_cmd(char *name, OSP_FUNCPTR pfunc, char *desc, uint32_t argnum)
{
    OSP_CMD_RTN *tlb   = NULL;
    uint8_t num        = 0;
    uint8_t i          = 0;
    uint8_t u8str_len = 0;

    if ((NULL == name) || NULL == pfunc || NULL == desc)
    {
        UCP_PRINT_ERROR("osp_insert_cmd_ext name:%p pfunc:%p desc:%p", name, pfunc, desc);
        return OSP_ERROR;
    }

    if (argnum > 6)
    {
        UCP_PRINT_ERROR("osp_insert_cmd argnum:%u beyond 6", argnum);
        return OSP_ERROR;
    }

    for (i = 0; i < MAX_EXT_CMD_NUM; i++)
    {
        if (strcmp(ospCmdRtnTbl[i].cmd, name) == 0)
        {
            UCP_PRINT_ERROR("arm cmd i:%u cmd:%s has exist name:%s", i, ospCmdRtnTbl[i].cmd, name);
            return OSP_ERROR;
        }
    }

    for (i = 0; i < MAX_EXT_CMD_NUM; i++)
    {
        if (strcmp(ospCmdRtnTblExt[i].cmd, name) == 0)
        {
            UCP_PRINT_ERROR("arm insert cmd i:%u cmd:%s has exist name:%s", i, ospCmdRtnTblExt[i].cmd, name);
            return OSP_ERROR;
        }
    }

    for (i = 0; i < MAX_EXT_CMD_NUM; i++)
    {
        if (strcmp(ospApeCmdRtnTbl[i].cmd, name) == 0)
        {
            UCP_PRINT_ERROR("ape cmd i:%u cmd:%s has exist name:%s", i, ospApeCmdRtnTbl[i].cmd, name);
            return OSP_ERROR;
        }
    }

    osp_sem_take(ospCmdInsertSem, -1);
    
    tlb = ospCmdRtnTblExt;
    num = SHELL_CMD_NUM_EXT;
    if(num >= MAX_EXT_CMD_NUM)
    {
        UCP_PRINT_ERROR("osp_insert_cmd num:%u beyond MAX_EXT_CMD_NUM:%d\r\n", num, MAX_EXT_CMD_NUM);
        return OSP_ERROR;
    }
    
    u8str_len = strlen(name);
    if(u8str_len > 12)
    {
        UCP_PRINT_ERROR("osp_insert_cmd u8str_len:%u beyond 12", u8str_len);
        return OSP_ERROR;
    }

    memcpy(tlb[num].cmd, name, strlen(name) + 1);
    memcpy(tlb[num].descption, desc, strlen(desc) + 1);
    tlb[num].wrapper  = (OSP_FUNCPTR)osp_shell_wrapper;
    tlb[num].routine  = pfunc;
    tlb[num].argnum   = argnum;

    SHELL_CMD_NUM_EXT++;
    
    osp_sem_give(ospCmdInsertSem);
    
    return OSP_OK;
}

int32_t osp_shell_init(void)
{

    ospCmdRtnTblExt      = (OSP_CMD_RTN *)osp_get_init_mem(sizeof(OSP_CMD_RTN) * MAX_EXT_CMD_NUM);
    ospCmdInsertSem      = (lx_sem_t *)osp_get_init_mem(sizeof(lx_sem_t));
    ospApeCmdInsertSem   = (lx_sem_t *)osp_get_init_mem(sizeof(lx_sem_t));

    if (0 == g_ProcessId)
    {
        memset(ospCmdRtnTblExt, 0, sizeof(OSP_CMD_RTN) *MAX_EXT_CMD_NUM);
        memset(ospApeCmdInsertSem, 0, sizeof(OSP_CMD_RTN) *MAX_EXT_CMD_NUM);
        osp_semsm_create(ospCmdInsertSem);
        osp_semsm_create(ospApeCmdInsertSem);
    }
	
    /*配置文件读取server ip ,port*/
	osp_server_get();	

    osp_insert_cmd("test", (OSP_FUNCPTR)osp_ushell_test, "arm insert test", 0);
    
    return 0;
}

void osp_ushell_output(const char *fmt, ...)
{
    uint32_t u32str_len  = 0;
    char  acstr[256]     = {0};
    va_list  st_va_list;

    if(NULL == fmt)
    {
        UCP_PRINT_ERROR("osp_ushell_output fmt is null");
        return;
    }
    
    va_start(st_va_list, fmt);
    u32str_len = vsprintf((char *)acstr, fmt, st_va_list);
    va_end(st_va_list);

    osp_net_shell_out(acstr, u32str_len);

    return;
}

void osp_ushell_test()
{
    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);

    USHELL_PRINT("%s", g_time_now);

    return;
}

bool osp_is_ape_cmd(char *pCmd)
{
    if(NULL == pCmd)
    {
        return false;
    }

    if (strstr(pCmd, "_ape"))
    {
        return true;
    }

    return false;
}

void osp_get_ape_id(uint8_t ucApeid)
{
    if (ucApeid > 7)
    {
        return;
    }

    guc_ape_id = ucApeid;
    
    return;
}

void osp_set_ape_log_mode(uint8_t ucIsEcho)
{
    if(ucIsEcho > 3)
    {
        UCP_PRINT_ERROR("osp_set_ape_log_mode error ucIsEcho:%u \n", ucIsEcho);
        return;
    }

    g_ulApeLogMode = ucIsEcho;

    osp_log_mode_cfg();
    
    UCP_PRINT_LOG("osp_set_ape_log_mode g_ulApeLogMode:%u \n", g_ulApeLogMode);
}

void osp_set_platform_log_mode(uint8_t ucIsEcho)
{
    if(ucIsEcho > 3)
    {
        UCP_PRINT_ERROR("osp_set_ape_log_mode error ucIsEcho:%u \n", ucIsEcho);
        return;
    }

    g_ucPlatformMode = ucIsEcho;

    UCP_PRINT_LOG("osp_set_ape_log_mode g_ucPlatformMode:%u \n", g_ucPlatformMode);
}


void osp_set_arm_log_mode(uint8_t ucIsNet)
{
    if(ucIsNet > 3)
    {
        UCP_PRINT_ERROR("osp_set_arm_log_mode error log_mode:%u \n", ucIsNet);
        return;
    }

    g_ulArmLogMode = ucIsNet;

    osp_log_mode_cfg();
    
    UCP_PRINT_LOG("osp_set_arm_log_mode g_ulArmLogMode:%u \n", g_ulArmLogMode);
}

void osp_reget_ape_cmd()
{
    g_u32ApeShellCmdNum = 0;

    osp_ape_msg_send((char *)"recmd_ape"); 

    return;
}

void osp_ape_insert_msg_send()
{
    
    UCP_PRINT_SHELL("osp_ape_insert_msg_send begin gac_cmd:%s\n", gac_cmd);
    osp_ape_msg_send((char *)gac_cmd); 
    UCP_PRINT_SHELL("osp_ape_insert_msg_send END\n");

    return;
}


void osp_show_ape_taskinfo()
{
    UCP_PRINT_SHELL("osp_show_ape_taskinfo cmd:%s\n", gac_cmd);    

    osp_ape_msg_send((char *)gac_cmd); 

    return;
}

void osp_set_print_level(uint8_t ucLevel)
{    
    if(ucLevel > 0x10)
    {        
        UCP_PRINT_SHELL("osp_set_print_level leve:%u\n", ucLevel);
        return;
    }
    
    guc_print_level = ucLevel;
    
    return;
}

void osp_show_print_level()
{   
    char pbuf[64];
    uint32_t len = 0;

    len = sprintf(pbuf,"arm print level:0x%x\n", guc_print_level);
    //UCP_PRINT_SHELL("%s\n", pbuf);
    
    osp_net_shell_out((char *)&pbuf, len);
    
    return;
}

void osp_set_oam(uint8_t ucOam)
{    
    if(ucOam > 5)
    {        
        UCP_PRINT_SHELL("osp_set_oam ucOam:%u\n", ucOam);
        return;
    }
    
    guc_oam = ucOam;
    
    return;
}


void osp_ape_set_log_level(uint8_t ucLevel)
{    
    if(ucLevel > 5)
    {        
        UCP_PRINT_ERROR("osp_ape_set_log_level leve:%u\n", ucLevel);
        return;
    }
    
    UCP_PRINT_SHELL("osp_ape_set_log_level begin cmd:%s\n", gac_cmd);
    osp_ape_msg_send((char *)gac_cmd); 

    return;
}

void osp_ape_csu_stop_cfg(uint8_t ucstop, uint8_t ucadvance)
{        
    char aCmd[32] = {0};
    
    if(ucstop > 2)
    {        
        UCP_PRINT_ERROR("osp_csu_stop_cfg ucstop:%u\n", ucstop);
        return;
    }

    sprintf(aCmd, "%s %u\r\n", gac_cmd, ucstop);

    UCP_PRINT_SHELL("osp_csu_stop_cfg aCmd:%s\n", aCmd);
    osp_ape_msg_send((char *)aCmd); 

    return;
}


void osp_ape_csu_int_cnt()
{

    UCP_PRINT_LOG("osp_ape_csu_int_cnt intr_ape\n");    

    osp_ape_msg_send((char *)"intr_ape"); 

    return;
}


void osp_ape_msg_send(char *pcmd)
{
    uint8_t i           = 0;
    int8_t *pi8buf      = NULL;	
    uint16_t u16offset = sizeof(osp_sw_msg_info_t);
	osp_sw_msg_info_t stMsg;

    if(NULL == pcmd)
    {
        return;
    }
    
    for(i = 12;i < 24; i++)
    {
        pi8buf = osp_sw_mem_malloc(i);
        if (NULL == pi8buf)
        {
            UCP_PRINT_ERROR("osp_ape_msg_send call spu_sw_mem_malloc return null\n");
            return ;
        }
        
        memset((char *)stMsg.i8Data, 0, strlen(pcmd));

        stMsg.u8PktType  = UCP4008_OSP_SHELL;
        stMsg.u8CoreId   = i-12; /*spu core id*/
        stMsg.u16DataLen = sizeof(osp_sw_msg_info_t)+strlen(pcmd);
        memcpy((char *)stMsg.i8Data ,pcmd, strlen(pcmd));

		memcpy((void *)(pi8buf-u16offset), (void *)&stMsg, stMsg.u16DataLen);

        //UCP_PRINT_LOG("u8PktType:%d cmd:%s u8CoreId:%u len:%d\n",  stMsg.u8PktType, stMsg.i8Data, stMsg.u8CoreId, stMsg.u16DataLen);

        osp_sw_enque(i, pi8buf);
    }

    return;
}

void osp_cmd_register(OSP_CMD_EXT *pCmdExt)
{
    uint32_t num = 0;
    uint32_t i   = 0;

    if (NULL == pCmdExt)
    {
        UCP_PRINT_ERROR("osp_cmd_register pCmdExt is null");
        return;
    }

    UCP_PRINT_LOG("osp_cmd_register ape cmd:%s", pCmdExt->cmd);

    for (i = 0; i < MAX_EXT_CMD_NUM; i++)
    {
        if (strcmp(ospCmdRtnTbl[i].cmd, pCmdExt->cmd) == 0)
        {
            UCP_PRINT_LOG("osp_cmd_register arm cmd i:%u cmd:%s has exist name:%s", i, ospCmdRtnTbl[i].cmd, pCmdExt->cmd);
            return ;
        }
    }

    for(i =0; i <SHELL_CMD_NUM_EXT; i++)
    {
        if (0 == strcmp(ospCmdRtnTblExt[i].cmd, pCmdExt->cmd))
        {
            UCP_PRINT_LOG("osp_cmd_register cmd:%s has exist name:%s", i, ospCmdRtnTblExt[i].cmd,  pCmdExt->cmd);
            return;
        }
    }

    for(i =0; i <g_u32ApeShellCmdNum; i++)
    {
        if (0 == strcmp(ospApeCmdRtnTbl[i].cmd, pCmdExt->cmd))
        {
            UCP_PRINT_LOG("osp_cmd_register ape cmd:%s has exist name:%s", ospApeCmdRtnTbl[i].cmd,  pCmdExt->cmd);
            return;
        }
    }

    num = g_u32ApeShellCmdNum;
    
    strcpy(ospApeCmdRtnTbl[num].cmd, pCmdExt->cmd);
    ospApeCmdRtnTbl[num].wrapper = (OSP_FUNCPTR)osp_ape_shell_wrapper;
    ospApeCmdRtnTbl[num].argnum = pCmdExt->argnum;

    g_u32ApeShellCmdNum++;

    return ;
}

void osp_ape_cmd_show()
{
    uint8_t i    = 0;
    uint32_t len = 0;
    char pbuf[2048];

    for(i = 0; i < g_u32ApeShellCmdNum; i++)
    {
	    len += sprintf(pbuf +len,"cmd:%s argnum:%u\n", ospApeCmdRtnTbl[i].cmd, ospApeCmdRtnTbl[i].argnum);
    }

    osp_net_shell_out(pbuf, len);

    return;
}

void osp_arm_cmd_show()
{
    uint8_t i    = 0;
    uint32_t len = 0;
    char pbuf[2048];

    for(i = 0; i < SHELL_CMD_NUM_EXT; i++)
    {
	    len += sprintf(pbuf +len,"cmd:%s argnum:%u\n", ospCmdRtnTblExt[i].cmd, ospCmdRtnTblExt[i].argnum);
    }

    osp_net_shell_out(pbuf, len);

    return;
}

#if 0
void osp_cmd_insert_proc(Osp_Ape_Msg_Head *pMsg)
{
    char *pbuf         = NULL;
    OSP_CMD_RTN *tlb   = NULL;
    uint32_t num       = 0;

    if (NULL == pMsg)
    {
        return;
    }

    osp_sem_take(ospCmdInsertSem, -1);
    
    pbuf  = APE_MSG_HEAD_TO_COMM(pMsg);
    
    tlb = (OSP_CMD_RTN *)pbuf;
    num = SHELL_CMD_NUM_EXT;

    strcpy(ospCmdRtnTblExt[num].cmd, tlb->cmd);
    strcpy(ospCmdRtnTblExt[num].descption, tlb->descption);
    ospCmdRtnTblExt[num].wrapper = (OSP_FUNCPTR)osp_ape_shell_wrapper;
    ospCmdRtnTblExt[num].argnum = tlb->argnum;
    
    UCP_PRINT_SHELL("osp_cmd_insert_proc  num:%u cmd:%s descption:%s argnum:%u", SHELL_CMD_NUM_EXT, ospCmdRtnTblExt[num].cmd, ospCmdRtnTblExt[num].descption, ospCmdRtnTblExt[num].argnum);

    SHELL_CMD_NUM_EXT++;
    osp_sem_give(ospCmdInsertSem);

    return;
}
#endif

void osp_cmd_insert_proc(osp_sw_msg_info_t *pMsg)
{
    char *pbuf           = NULL;
    uint32_t ulLen       = 0;
    OSP_CMD_EXT stCmdExt;

    if (NULL == pMsg)
    {
        return;
    }

    osp_sem_take(ospApeCmdInsertSem, -1);
    
    pbuf  = SPU_SHELL_MSG_HEAD_TO_COMM(pMsg);
    ulLen = SPU_SHELL_MSG_DADA_LEN(pMsg);  
    
    memcpy(&stCmdExt, pbuf, ulLen);
    
    switch(pMsg->u8CoreId)
    {
        case 0:
        case 1:
        case 2:
        case 3:
        case 4:
        case 5:
        case 6:
        case 7:
        case 8:
        case 9:
        case 10:
        case 11:
            osp_cmd_register(&stCmdExt);
            break;
    }

    osp_sem_give(ospApeCmdInsertSem);
    
    return;
}

void osp_ape_shell_out(Osp_Ape_Msg_Head *pMsg)
{
#if 0
    bool bIsApeCmd = false;
    
    if (NULL == pMsg)
    {
        return;
    }

    UCP_PRINT_LOG("osp_ape_shell_out pMsg:%p MsgType: 0x%x pMsg->msg_size:%u src_core_id: %u", (char *)pMsg,pMsg->msg_type, pMsg->msg_size ,pMsg->src_core_id);

    bIsApeCmd = osp_is_ape_cmd_insert(pMsg);
    
    switch(pMsg->msg_type)
    {
        case UCP4008_OSP_SHELL:
        case UCP4008_OSP_SHELL_ECHO:
             if(true == bIsApeCmd)
             {
                 osp_cmd_insert_proc(pMsg);
                 break;
             }
             write(STDOUT_FILENO, APE_MSG_HEAD_TO_COMM(pMsg), APE_MSG_DADA_LEN(pMsg));
             break;
        case OSP_STR_LOG:
        case OSP_BIN_LOG:
             osp_dbg_log_main(pMsg);
             break;
        default:
             UCP_PRINT_ERROR("osp_ape_shell_out pMsg:%p MsgType: 0x%x pMsg->msg_size:%u src_core_id: %u", (char *)pMsg,pMsg->msg_type, pMsg->msg_size ,pMsg->src_core_id);
             break;
    }
#endif   
    return;

}

void osp_ape_shell_proc(osp_sw_msg_info_t *pMsg)
{    
    if (NULL == pMsg)
    {
        return;
    }

   UCP_PRINT_LOG("osp_ape_shell_proc u8PktType:%d cmd:%s u8CoreId:%u u16DataLen:%u\n",  pMsg->u8PktType, pMsg->i8Data, pMsg->u8CoreId, pMsg->u16DataLen);
    
    switch(pMsg->u8PktType)
    {
        case UCP4008_OSP_SHELL:
        case UCP4008_OSP_SHELL_ECHO:
             //write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             osp_net_shell_out((char *)pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case UCP4008_OSP_SHELL_REG:
             osp_cmd_insert_proc(pMsg);
             break;
        default:
             UCP_PRINT_ERROR("osp_ape_shell_proc u8PktType:%d cmd:%s u8CoreId:%u u16DataLen:%u\n",  pMsg->u8PktType, pMsg->i8Data, pMsg->u8CoreId, pMsg->u16DataLen);
             break;
    }
   
    return;

}

void osp_show_info_by_coreid(osp_sw_msg_info_t *pMsg)
{
    if (NULL == pMsg)
    {
        return;
    }

    switch(pMsg->u8CoreId)
    {
        case 0:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 1:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 2:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 3:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 4:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 5:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 6:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 7:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 8:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 9:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 10:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        case 11:
             write(STDOUT_FILENO, pMsg->i8Data, SPU_SHELL_MSG_DADA_LEN(pMsg));
             break;
        default:
             UCP_PRINT_SHELL("osp_ape_shell_proc u8PktType:%d cmd:%s u8CoreId:%u u16DataLen:%u\n",  pMsg->u8PktType, pMsg->i8Data, pMsg->u8CoreId, pMsg->u16DataLen);
             break;
    }

    return;
}


uint64_t osp_shell_task(void)
{
    uint8_t u8loop      = 0;
    osp_sw_msg_info_t *pstsw_msg = NULL;
    static uint32_t su32LogCnt = 0;

    ++su32LogCnt;
    //printf("LogTask Enter >>> %d\r\n", su32LogCnt);

    /* 从软队列里取出 */
    for(u8loop = 24; u8loop < 36; u8loop++)
    {
        while(OSP_OK == osp_sw_deque(u8loop, &pstsw_msg))
        {
            UCP_PRINT_LOG("u8loop = %d, addr = %p, len = %d, coreid = %d, type = %d\r\n", u8loop, pstsw_msg, pstsw_msg->u16DataLen, pstsw_msg->u8CoreId, pstsw_msg->u8PktType);
            osp_ape_shell_proc(pstsw_msg);
        }
    }
    
    usleep(10);

    return OSP_OK;
}

uint32_t rev_shell_log_data(uint32_t port_id,uint32_t queue_num,uint32_t el_ind,const char* buf,uint32_t remainedLength,uint32_t* handledLength)
{    
#if 0
    //osp_get_current_time();
    //UCP_PRINT_DEBUG("rev_shell_log_data begin %s\n",  g_time_now);
    Osp_Ape_Msg_Head *pMsg = NULL;

    if(NULL == buf)
    {
        return 1;
    }

    pMsg = (Osp_Ape_Msg_Head*)buf;
    *handledLength = pMsg->msg_size;

    /*队列UCP4008_TRAFFIC_LOG*/
    if(7 == queue_num) 
    {
        UCP_PRINT_LOG("rev_shell_log_data queue_num[%u] el_ind[%u] buf[%p]!\n",  queue_num, el_ind, buf);
        osp_ape_shell_out(pMsg);        
        osp_msg_transfer_free(7, 0, (char *)pMsg);
	}
    else
    {
        UCP_PRINT_LOG("rev_shell_log_data free queue_num[%u] el_ind[%u] buf[%p]!\n",  queue_num, el_ind, buf);
        /*释放UCP4008_TRAFFIC_LOG*/
        osp_msg_transfer_free(7, 0, (char *)pMsg);
    } 
    
    //osp_get_current_time();
    //UCP_PRINT_SHELL("rev_shell_log_data end %s\n",  g_time_now);
#endif
    return 0;
}


void osp_show_queue_ul_info()
{
	PetSmLocalMgt_t* pPetSmLocalMgt = get_pet_sm_local_mgt();
    uint8_t i,j;    
    uint32_t len = 0;
    char pbuf[2048];

    len = sprintf(pbuf,"\ninst_id\tque_id\t\ttype_id\t\talloc\t\t\tape_tx_num\t\t\tarm_rx_num\n\r");

    for (i = 0; i < MAX_INSTANCE_NUM; i++) {
    	for (j = 0; j < UCP4008_TRAFFIC_MAX_NUM; j++) {
            len += sprintf(pbuf +len,"%d        %d\t\t%-4d\t\t%-10d\t\t%10d\t\t\t%10d\n", i, j, pPetSmLocalMgt->pQueueCfg[i][j]->handler.type_id, pPetSmLocalMgt->pUlQueue[i][j]->alloc, pPetSmLocalMgt->pUlQueue[i][j]->in, pPetSmLocalMgt->pUlQueue[i][j]->out); 
		}
    }

    //printf("%s", pbuf);
    osp_net_shell_out(pbuf, len);
    
    return;
}

void osp_show_queue_dl_info()
{
	PetSmLocalMgt_t* pPetSmLocalMgt = get_pet_sm_local_mgt();
    uint8_t i,j;
    uint32_t len = 0;
    char pbuf[2048];
    
    len = sprintf(pbuf,"\ninst_id\tque_id\t\ttype_id\t\talloc\t\t\tarm_tx_num\t\t\tape_rx_num\n\r");

    for (i = 0; i < MAX_INSTANCE_NUM; i++) {
    	for (j = 0; j < UCP4008_TRAFFIC_MAX_NUM; j++) {
            len += sprintf(pbuf +len, "%d        %d\t\t%-4d\t\t%-10d\t\t%10d\t\t\t%10d\n", i, j, pPetSmLocalMgt->pQueueCfg[i][j]->handler.type_id, pPetSmLocalMgt->pDlQueue[i][j]->alloc, pPetSmLocalMgt->pDlQueue[i][j]->in, pPetSmLocalMgt->pDlQueue[i][j]->out); 
		}
    }

    //printf("%s", pbuf);
    osp_net_shell_out(pbuf, len);

    return;
}

int8_t osp_server_cfg(uint8_t *ip, uint32_t ulport)
{
    int8_t ret      = 0;
    FILE *fp = NULL;

    if(NULL == ip)
    {
        UCP_PRINT_SHELL("ip is null");
        return ret;
    }

    memcpy(gst_server_log.ip, ip, 15);
    gst_server_log.ulport = ulport;

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

    fp = fopen("./server/logmode", "w+");
    if (fp < 0)
    {
        UCP_PRINT_ERROR("osp_server_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("fwrite error ret:%d\n", ret);
        fclose(fp);
        return ret;
    }
    
    fflush(fp);
    fclose(fp);

    return ret;
}

void osp_server_cfg_show()
{
    uint32_t len = 0;
    char pbuf[2048];

	len = sprintf(pbuf,"ip:%s\nport:%u\napelog:%u\narmlog:%u\nplatformlog:%u\nlogpath:%s\n", \
	                  gst_server_log.ip, gst_server_log.ulport, g_ulApeLogMode, g_ulArmLogMode, g_ucPlatformMode, gst_server_log.path);

    //printf("%s", pbuf);
    osp_net_shell_out(pbuf, len);

    return;
}


void osp_log_path_cfg(char *path)
{
    int32_t ret = 0;
    FILE *fp    = NULL;

    if(NULL == path)
    {
        UCP_PRINT_SHELL("path is null");
        return;
    }

    if (access(path, F_OK) != 0)
    {
        osp_mkdirs(path, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); 
    }
    
    memset(gst_server_log.path, 0, 128);
    sprintf((char *)gst_server_log.path, "%s", path);

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

	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;
    }
    
    fflush(fp);
    fclose(fp);

    sleep(1);
    osp_log_cfg_reload();

    return;
}



void osp_server_get()
{
    FILE *fp = NULL;

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

    fp = fopen("./server/logmode", "r+");
    if (NULL == fp)
    {
        UCP_PRINT_ERROR("osp_server_get file open failure  \n");
        return;
    }

	fscanf(fp,"%s %d\n", gst_server_log.ip, &gst_server_log.ulport);

	/*ret = fread((char *)&gst_server_log, sizeof(char), sizeof(Osp_Server_Head), fp);
    if(ret < 0)
    {
        UCP_PRINT_ERROR("fwrite read ret:%d\n", ret);
        fclose(fp);
        return ret;
    }*/
    
    fclose(fp);

    return;
}


int32_t osp_shell_main()
{
    struct termios nt;
    int32_t ret;
    char shellbuf[MAX_CMD_LEN] = {0};
    tcgetattr(STDIN_FILENO, &saveterm);
    nt = saveterm;
    nt.c_lflag &= (~ICANON);
    nt.c_lflag &= (~ECHO);
    nt.c_cc[VMIN] = 1;
    nt.c_cc[VTIME] = 0;
    tcsetattr(STDIN_FILENO, TCSANOW, &nt);

    //arg = (char **)malloc(maxCmdField * sizeof(arg[0]));
    arg = (char **)gul_arg;
        
    osp_set_prompt();
    {
        osp_shell_get_line();
        memcpy(shellbuf, szCmdNow, strlen(szCmdNow)); 
        shellbuf[strlen(szCmdNow)] = '\0';

        osp_getcmdarg(szCmdNow); 
        ret = osp_execcmd();
        
        if (OSP_ERROR == ret)
        {
            system(shellbuf); 
        }
    }
    //free(arg);
    
    return ret;
}

#if 0
void osp_get_tfu_location_info(    )
{
    location_info_s stlocat_ptr;

    get_tfu_location_info(&stlocat_ptr);

    UCP_PRINT_SHELL("latitude:%d longitude:%d altitude:%d\n\r",stlocat_ptr.latitude, stlocat_ptr.longitude, stlocat_ptr.altitude);

    return;
}

void osp_get_clock_tracking_state(void)
{
    int32_t u32ret = 0;
    tracking_info_s sttrk_ptr;
    
    u32ret = get_clock_tracking_state(&sttrk_ptr);
    if(OSP_OK != u32ret)
    {
        return;
    }

    UCP_PRINT_SHELL("lock_flag:%d leap_valid:%d view_sats:%d\n\r",sttrk_ptr.lock_flag, sttrk_ptr.leap_valid, sttrk_ptr.view_sats);
    UCP_PRINT_SHELL("track_sats:%d survey_in:%d alma_complete:%d\n\r",sttrk_ptr.track_sats, sttrk_ptr.survey_in, sttrk_ptr.alma_complete);

    return;
}

void osp_reset_clock_module(void)
{
    int32_t i32ret = 0;
    
    i32ret = reset_clock_module();
    if(OSP_OK != i32ret)
    {
        UCP_PRINT_SHELL("i32ret:%d\n\r", i32ret);
        return;
    }

    return;
}

void osp_set_clk_mode(clk_flag_e pseudo_flag)
{
    if(pseudo_flag > 1)
    {
        UCP_PRINT_SHELL("pseudo_flag :%d should be 0 or 1\n\r", pseudo_flag);
        return;
    }

    set_clk_mode(pseudo_flag);

    return;
}
#endif

void osp_show_swqueue_info()
{
    uint8_t i;
    uint16_t u16Size = SPU_SW_QUEUE_SHARE_INFO_SIZE;

    spu_sw_queue_share_info_t *pstsw_queue_share_ture = NULL;
    spu_sw_queue_share_info_t *pstsw_queue_share_base = (spu_sw_queue_share_info_t*)gpsw_que_share_mem;
    
    printf("queue\tdeque_id\tenque_id\talloc_id\tfree_id\n\r");

    for (i = 12; i < 24; i++)
    {
            pstsw_queue_share_ture = (spu_sw_queue_share_info_t*)((int8_t*)pstsw_queue_share_base + i*u16Size);
            printf("%d\t%4d\t\t%4d\t\t%4d\t\t%4d\n",
                    i, 
                    pstsw_queue_share_ture->u16queue_deque_idx, 
                    pstsw_queue_share_ture->u16queue_enque_idx, 
                    pstsw_queue_share_ture->u16queue_alloc_idx, 
                    pstsw_queue_share_ture->u16queue_free_idx);
    }
    
    return;
}



