#include "./include/m2ua_pub.h"
#include "./include/m2ua.h"
#include "./include/m2ua_const.h"
#include "./include/m2ua_struct.h"
#include "./include/m2ua_ext.h"
#include "../../debug/src/include/debug.h"

#define M2UA_DEBUG_ID	16
#define	M2UA_VER_DEBUG	"V1.0.01"
#define	M2UA_PATCH	2

extern int m2ua_set_traffic_mode_type(int flag);
extern int set_asp_id_order(BYTE flag);

static char ascii[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
						 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};

static BYTE	log_help[] = {
"M2UA Debug Monitor Help:\n\r\
\n\r\
1.[help]                                display help menu\n\r\
2.[log all/none]                        display all/none logs\n\r\
3.[log error on/off]                    display error logs (sg only)\n\r\
4.[log mtp3/maup on/off]                display mtp3/maup logs (sg or link)\n\r\
5.[log m2ua/sctp on/off]                display m2ua/sctp logs (sg only)\n\r\
6.[log sg-xxx/lk-xxx on/off]            display sg/lk logs\n\r\n\r"
};

static	WORD	disp_page[10];
static	BYTE	*disp_ptr = (BYTE *) disp_page;

static 	DWORD	debug_status_id[20] = 
	{1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,1};
	
static	BYTE 	debug_status = 1;

static DWORD	debug_name_id[20] = 
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,2
	};
	
static DWORD	debug_ascin_id[20] = 
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,3
	};

static DWORD	debug_ascout_id[20] = 
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,4
	};
		
static	DWORD	debug_page_title[20] = 		
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,1,1
	};
	
static	DWORD	debug_page_line[20] = 		
	{
		1,3,6,1,4,1,1373,1,1,2,3,1,2,M2UA_DEBUG_ID + 2,1,2,1
	};
		
const static BYTE	PAGE_POINT 	= 14;
const static BYTE  	LINE_POINT 	= 15;
const static BYTE	BASE_ID_LEN = 15;

static BYTE	title1_p[] = 
{
	"    M2UA    Page 01    SG Para\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
Subpage\n\r\
SG_Para\n\r"
};

static BYTE	title2_p[] = 
{
	"    M2UA    Page 02    Link Para\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
Subpage\n\r\
LK_Para\n\r"
};

static BYTE	title3_p[] = 
{
	"    M2UA    Page 03    SG Info\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
Subpage\n\r\
SG_Info\n\r"
};

static BYTE	title4_p[] = 
{
	"    M2UA    Page 04    Link Info\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
LK_Info\n\r"
};

static BYTE	title5_p[] = 
{
	"    M2UA    Page 05    SG CSTA\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
Subpage\n\r\
SG_CSTA\n\r"
};

static BYTE	title6_p[] = 
{
	"    M2UA    Page 06    Link CSTA\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
LK_CSTA\n\r"
};

static BYTE	title7_p[] = 
{
	"    M2UA    Page 07    Watchdog\n\r\
                   0  1  2  3  4  5  6  7  8  9  10 11 12 13 14 15\n\r\
Watchdog\n\r"
};

BYTE m2ua_disp_line(BYTE page, BYTE line)
{
	BYTE	disp_length;
	
	disp_length = 16;
	disp_ptr 	= (BYTE *) disp_page;
	
	switch (page)
	{
		case 1:	// Page 1: SG Para
			if (line == 0)
			{
				disp_ptr 	= (BYTE *) &disp_page[page];
				disp_length = 2;
			}
			else if (line < 17)
			{
				disp_ptr 	= (BYTE *) m2ua_para.sg_para + ((line - 1) * sizeof(sg_para_t)) + (disp_page[page] * 16 * sizeof(sg_para_t));
				disp_length = sizeof(sg_para_t);
			}
			else
				disp_length = 0;
			break;
		case 2:	// Page 2: LK Para
			if (line == 0)
			{
				disp_ptr 	= (BYTE *) &disp_page[page];
				disp_length = 2;
			}
			else if (line < 17)
			{
				disp_ptr 	= (BYTE *) m2ua_para.lk_para + ((line - 1) * sizeof(lk_para_t)) + disp_page[page] * 16 * sizeof(lk_para_t);
				disp_length = sizeof(lk_para_t);
			}
			else
				disp_length = 0;
			break;
		case 3:	// Page 3: SG Info
			if (line == 0)
			{
				disp_ptr 	= (BYTE *) &disp_page[page];
				disp_length = 2;
			}
			else if (line < 7)
				disp_ptr 	= (BYTE *) &m2ua_sg_info[disp_page[page]] + ((line - 1) * 16);
			else
				disp_length = 0;
			break;
		case 4:	// Page 4: LK Info
			if (line == 0)
			{
				disp_ptr 	= (BYTE *) &disp_page[page];
				disp_length = 2;
			}
			else if (line < 17)
			{
				disp_ptr 	= (BYTE *) m2ua_lk_info + ((line - 1) * sizeof(m2ua_lk_info_t)) + disp_page[page] * 16 * sizeof(m2ua_lk_info_t);
				disp_length = sizeof(m2ua_lk_info_t);
			}
			else
				disp_length = 0;
			break;
		case 5:	// Page 5: SG CSTA
			if (line == 0)
			{
				disp_ptr 	= (BYTE *) &disp_page[page];
				disp_length = 2;
			}
			else if (line < 3)
				disp_ptr 	= (BYTE *) &m2ua_csta.sg_csta[disp_page[page]] + ((line - 1) * 16);
			else
				disp_length = 0;
			break;
		case 6:	// Page 6: LK CSTA
			if (line == 0)
			{
				disp_ptr 	= (BYTE *) &disp_page[page];
				disp_length = 2;
			}
			else if (line < 3)
				disp_ptr 	= (BYTE *) &m2ua_csta.lk_csta[disp_page[page]] + ((line - 1) * 16);
			else
				disp_length = 0;
			break;
		case 7:	// Page 7: Err
			if (line < 16)
				disp_ptr = (BYTE *)err + (line * 16);
			else
				disp_length = 0;
			break;
		default:
			disp_length = 0;
			break;
	}
	
	return disp_length;
}

void m2ua_disp_page(BYTE page)
{
	BYTE	disp_line;
	BYTE	disp_length;

	debug_page_line[PAGE_POINT] = page + 5;
	
	for (disp_line = 0; disp_line < 22; disp_line++)
	{
		disp_length = m2ua_disp_line(page, disp_line);
		debug_page_line[LINE_POINT] = disp_line + 2;
		debug_page_line[LINE_POINT + 1] = 2;	// Data Pointer
		debug_set_response(BASE_ID_LEN + 2, debug_page_line, disp_ptr, disp_length);
	}
}

int	m2ua_debug_set(void)
{
	BYTE	page;
	BYTE	data[10];
	BYTE 	*ptr;
	
	bzero(disp_page, 20);
	ptr = data;
	
	debug_set_response(BASE_ID_LEN, debug_status_id, &debug_status, 1);
	debug_set_response(BASE_ID_LEN, debug_name_id, (BYTE *)M2UA_VER_DEBUG, 10);
	debug_set_response(BASE_ID_LEN, debug_ascin_id, (BYTE *)m2ua_asciin_buf, 4096);
	debug_set_response(BASE_ID_LEN, debug_ascout_id, (BYTE *)m2ua_asciout_buf, 4096);
	
	for (page = 1; page < 8; page++)
	{
		switch (page)
		{
			case 1: //page 1
				ptr = title1_p;
				break;
			case 2: //page 2
				ptr = title2_p;
				break;
			case 3: //page 3
				ptr = title3_p;
				break;
			case 4: //page 4
				ptr = title4_p;
				break;
			case 5: //page 5
				ptr = title5_p;
				break;
			case 6: //page 6
				ptr = title6_p;
				break;
			case 7: //page 7
				ptr = title7_p;
				break;
			default:
				break;				
		}
		
		debug_page_title[PAGE_POINT] = 5 + page;
		debug_set_response(BASE_ID_LEN + 1, debug_page_title, ptr, strlen((char *)ptr));
		m2ua_disp_page(page);
	}
	
	return 1;
}

int	m2ua_asciout_proc(char *out_str)
{
	int out_len;
	
	out_len = strlen(out_str);
		
	if (out_len + strlen(m2ua_asciout_buf) > MAX_ASCIIOUT_LEN - 2)
	{
		strcpy(m2ua_asciout_buf, out_str);
	}
	else
		strcat(m2ua_asciout_buf, out_str);
	
	return 1;
}

void m2ua_mon(void)
{
	BYTE	in_page, err_fg = 0;
	char	*ascii_in_ptr 	= NULL;
	char	*str_start 		= NULL;
	WORD	str_len, num;
	
	if ((str_len = strlen(m2ua_asciin_buf)) > 0)
	{
		in_page = (BYTE)m2ua_asciin_buf[0] - 1;
		ascii_in_ptr = m2ua_asciin_buf + 1;
		
		if (in_page > 7)
			err_fg = 1;
		else if (strcmp(ascii_in_ptr,"c") == 0)
		{
			bzero(&m2ua_csta, sizeof(m2ua_csta_t));
			bzero(err, 256);
		}
		else if (strcmp(ascii_in_ptr,"log mtp3 on") == 0)
		{
			moniter_fg = moniter_fg | MONITOR_MTP3;
		}
		else if (strcmp(ascii_in_ptr,"log mtp3 off") == 0)
		{
			moniter_fg = moniter_fg & (~MONITOR_MTP3);			
		}
		else if (strcmp(ascii_in_ptr,"log m2ua on") == 0)
		{
			moniter_fg = moniter_fg | MONITOR_M2UA;
		}
		else if (strcmp(ascii_in_ptr,"log m2ua off") == 0)
		{
			moniter_fg = moniter_fg & (~MONITOR_M2UA);			
		}
		else if (strcmp(ascii_in_ptr,"log maup on") == 0)
		{
			moniter_fg = moniter_fg | MONITOR_MAUP;
		}
		else if (strcmp(ascii_in_ptr,"log maup off") == 0)
		{
			moniter_fg = moniter_fg & (~MONITOR_MAUP);
		}
		else if (strcmp(ascii_in_ptr,"log sctp on") == 0)
		{
			moniter_fg = moniter_fg | MONITOR_SCTP;
		}
		else if (strcmp(ascii_in_ptr,"log sctp off") == 0)
		{
			moniter_fg = moniter_fg & (~MONITOR_SCTP);			
		}
		else if (strcmp(ascii_in_ptr,"log error on") == 0)
		{
			moniter_fg = moniter_fg | MONITOR_ERROR;
		}
		else if (strcmp(ascii_in_ptr,"log error off") == 0)
		{
			moniter_fg = moniter_fg & (~MONITOR_ERROR);			
		}
		else if (strcmp(ascii_in_ptr,"log all") == 0)
		{
			moniter_fg = MONITOR_ALL;
			if (!m2ua_sg_mon_count && !m2ua_lk_mon_count)
			{
				memset(m2ua_sg_mon_fg, 1, M2UA_MAX_SG_FSM_NUM);
				memset(m2ua_lk_mon_fg, 1, M2UA_MAX_LK_NUM);
			}
			else
				err_fg = 2;
		}
		else if (strcmp(ascii_in_ptr,"log none") == 0)
		{
			moniter_fg = MONITOR_NONE;
			memset(m2ua_sg_mon_fg, 0, M2UA_MAX_SG_FSM_NUM);
			memset(m2ua_lk_mon_fg, 0, M2UA_MAX_LK_NUM);
			m2ua_sg_mon_count = 0;
			m2ua_lk_mon_count = 0;
		}
		else if (strcmp(ascii_in_ptr,"help") == 0)
		{
			m2ua_asciout_proc((char *)log_help);
			sprintf(m2ua_ascitemp_buf, "Ver.%s T%03d\r\n",M2UA_VER_DEBUG,M2UA_PATCH);
			m2ua_asciout_proc(m2ua_ascitemp_buf);
		}
		else if (strstr(ascii_in_ptr, "log sg") != NULL)
		{
			if ((moniter_fg == MONITOR_ALL) &&
				!m2ua_sg_mon_count &&
				!m2ua_lk_mon_count)
				err_fg = 3;
			else if ((str_start = strstr(ascii_in_ptr, "-")) != NULL)
			{
				num = strtoul(str_start + 1, NULL, 10);
				if (num >= M2UA_MAX_SG_FSM_NUM)
					err_fg = 1;
				else if (strstr(ascii_in_ptr, "on") != NULL)
				{
					m2ua_sg_mon_fg[num] = 1;
					if (m2ua_sg_mon_count < M2UA_MAX_SG_NUM+2)
						m2ua_sg_mon_count++;
				}
				else if (strstr(ascii_in_ptr, "off") != NULL)
				{
					m2ua_sg_mon_fg[num] = 0;
					if (m2ua_sg_mon_count > 0)
						m2ua_sg_mon_count--;
				}
				else
					err_fg = 1;
			}
			else
				err_fg = 1;
		}
	       else if (strcmp(ascii_in_ptr,"tmt=override") == 0)
		{
			m2ua_set_traffic_mode_type(0);
		}	
	       else if (strcmp(ascii_in_ptr,"tmt=loadshare") == 0)
		{
			m2ua_set_traffic_mode_type(1);
		}		
		else if (strcmp(ascii_in_ptr,"asp id order0") == 0)
		{
			set_asp_id_order(0);			
		}	
		else if (strcmp(ascii_in_ptr,"asp id order1") == 0)
		{
			set_asp_id_order(1);			
		}			   
		else if (strstr(ascii_in_ptr, "log lk") != NULL)
		{
			if ((moniter_fg == MONITOR_ALL) &&
				!m2ua_sg_mon_count &&
				!m2ua_lk_mon_count)
				err_fg = 3;
			else if ((str_start = strstr(ascii_in_ptr, "-")) != NULL)
			{
				num = strtoul(str_start + 1, NULL, 10);
				if (num >= M2UA_MAX_LK_NUM)
					err_fg = 1;
				else if (strstr(ascii_in_ptr, "on") != NULL)
				{
					m2ua_lk_mon_fg[num] = 1;
					if (m2ua_lk_mon_count < M2UA_MAX_LK_NUM)
						m2ua_lk_mon_count++;
				}
				else if (strstr(ascii_in_ptr, "off") != NULL)
				{
					m2ua_lk_mon_fg[num] = 0;
					if (m2ua_lk_mon_count > 0)
						m2ua_lk_mon_count--;
				}
				else
					err_fg = 1;
			}
			else
				err_fg = 1;
		}
		else if (isdigit(ascii_in_ptr[0]))
		{
			num = strtoul(ascii_in_ptr, NULL, 10);
			disp_page[in_page] = num;
			m2ua_disp_page(in_page);
		}
		else if ((str_start = strstr(ascii_in_ptr, ">")) != NULL)
		{
			num = strtoul(str_start + 1, NULL, 10);
			disp_page[in_page] += num;
			m2ua_disp_page(in_page);
		}
		else if ((str_start = strstr(ascii_in_ptr, "<"))!= NULL)
		{
			num = strtoul(str_start + 1, NULL, 10);
			disp_page[in_page] -= num;
			m2ua_disp_page(in_page);
		}
		else
			err_fg = 1;
		
		if (err_fg == 0)
			m2ua_asciout_proc("Command OK!\n\r");
		else if (err_fg == 2)
			m2ua_asciout_proc("Log all for some SGs or Links!\n\r");
		else if (err_fg == 3)
			m2ua_asciout_proc("Log all already done for all SGs and Links, log none to clear!\n\r");
		else
			m2ua_asciout_proc("Command Error!\n\r");
		
		strcpy(m2ua_asciin_buf, "\0");
	}
}

int	m2ua_hex_to_ascii(BYTE *from_hex, WORD from_len, BYTE *to_asc)
{
	int	i, j;
	
	j = 0;
	if(from_len*3 > MAX_ASCITMP_LEN)
	{	
		m2ua_asciout_proc("\33[31m");
		sprintf(m2ua_ascitemp_buf, "m2ua_hex_to_ascii log msg is too long: %d\n\r", from_len);
		strcat(m2ua_ascitemp_buf, "\33[37m");
		m2ua_asciout_proc(m2ua_ascitemp_buf);
		return 0;
	}
	
	for (i = 0; i< from_len; i++)
	{
		to_asc[j] = ascii[from_hex[i] >> 4];
		j++;
		to_asc[j] = ascii[from_hex[i] & 0x0F];
		j++;
		to_asc[j] = ' ';
		j++;
	}
	
	to_asc[j] = '\0';
	
	return 1;
}

int m2ua_log_err(WORD sg_id, char *err_msg)
{
	if ((moniter_fg & MONITOR_ERROR) == MONITOR_ERROR)
	{
		if ((m2ua_sg_mon_fg[sg_id] == 0))
			return 0;
		m2ua_asciout_proc("\33[31m");
		if (strlen(err_msg) >= MAX_ASCITMP_LEN)
			sprintf(m2ua_ascitemp_buf, "SG[%d] log msg is too long: %zu\n\r", sg_id, strlen(err_msg));
		else
			sprintf(m2ua_ascitemp_buf, "SG[%d]: %s\n\r", sg_id, err_msg);
		strcat(m2ua_ascitemp_buf, "\33[37m");
		m2ua_asciout_proc(m2ua_ascitemp_buf);
	}
	
	return 1;
}
