/*
 *
 *  Copyright (C) 2007 Mindspeed Technologies, Inc.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include "cmm.h"
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "module_stat.h"

static int parse_interface(char *pstring, unsigned short *pinterface_number);

/************************************************************
 *
 *
 *
 ************************************************************/
void cmmStatShowPrintHelp()
{
	char buf[128];

	print_all_gemac_ports(buf, 128);
	cmm_print(DEBUG_STDOUT, "Usage: show stat queue {queue_no} interface {%s} query|query_reset\n"
				"       show stat interface {%s} query|query_reset\n"
				"       show stat vlan query|query_reset\n"
				"       show stat connection query\n"
				"       show stat pppoe query|query_reset\n"
				"       show stat bridge query|query_reset\n"
				"       show stat tunnel [name {tnl-name}] query|query_reset\n"
				"       show stat ipsec query|query_reset\n");				
}


/************************************************************
 *
 *
 *
 ************************************************************/
int cmmStatShowProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle)
{
	int cpt = tabStart;
	unsigned int cmdToSend = 0; /* bits field*/
	int rcvBytes = 0;
 	char rcvBuffer[256];
	char * endptr;
	unsigned int tmp;
	char *pinterface;
	unsigned short interface;

	fpp_stat_queue_cmd_t queueShowCmd;  
	fpp_stat_interface_cmd_t interfaceShowCmd;
	fpp_stat_connection_cmd_t connShowCmd;
	fpp_stat_pppoe_status_cmd_t pppoeStatusCmd;
	fpp_stat_bridge_status_cmd_t bridgeStatusCmd;
	fpp_stat_ipsec_status_cmd_t ipsecStatusCmd;
	fpp_stat_vlan_status_cmd_t vlanStatusCmd;
	fpp_stat_tunnel_status_cmd_t tunnelStatusCmd;
	fpp_stat_queue_response_t *queueStatRsp;
	fpp_stat_interface_pkt_response_t *interfacePktStatRsp;
	fpp_stat_conn_response_t *connStatRsp;

	uint64_t total_bytes_received_0;
	uint64_t total_bytes_received_1;
	uint64_t total_bytes_received;
	uint64_t total_bytes_transmitted_0;
	uint64_t total_bytes_transmitted_1;
	uint64_t total_bytes_transmitted;

	//goto help
	if(!keywords[cpt])
		goto help;

	if(strcasecmp(keywords[cpt], "queue") == 0)
	{
		if(!keywords[++cpt])
			goto help;

		/*Get an integer from the string*/
		endptr = NULL;
		tmp = strtoul(keywords[cpt], &endptr, 0);
		if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES))
		{
			cmm_print(DEBUG_CRIT, "Stat ERROR: Queue Number must be a number between 0 and %d\n", FPP_NUM_QUEUES - 1);
			goto help;
		}
		queueShowCmd.queue = tmp;

		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "interface") != 0) 
			goto keyword_error;

		if(!keywords[++cpt])
			goto help;

		pinterface = keywords[cpt];
		if (parse_interface(pinterface, &interface) < 0)
			goto help;

		queueShowCmd.interface = interface;

		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "query") == 0) 
		{
			queueShowCmd.action = FPP_CMM_STAT_QUERY;
		}
		else if(strcasecmp(keywords[cpt], "query_reset") == 0) 
		{
			queueShowCmd.action = FPP_CMM_STAT_QUERY_RESET;
		}
		else
			goto keyword_error;

		cmdToSend |= CMD_BIT(FPP_CMD_STAT_QUEUE);
	}
	else if(strcasecmp(keywords[cpt], "interface") == 0)
	{
		if(!keywords[++cpt])
			goto help;
									
		pinterface = keywords[cpt];
		if (parse_interface(pinterface, &interface) < 0)
			goto help;

		interfaceShowCmd.interface = interface;

		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "query") == 0) 
		{
			interfaceShowCmd.action = FPP_CMM_STAT_QUERY;
		}
		else if(strcasecmp(keywords[cpt], "query_reset") == 0) 
		{
			interfaceShowCmd.action = FPP_CMM_STAT_QUERY_RESET;
 		}
		else
			goto keyword_error;

		cmdToSend |= CMD_BIT(FPP_CMD_STAT_INTERFACE_PKT);
	}
	else if(strcasecmp(keywords[cpt], "connection") == 0)
	{
		if(!keywords[++cpt])
			goto help;
									
		if(strcasecmp(keywords[cpt], "query") != 0) 
			goto keyword_error;
		
		connShowCmd.action = FPP_CMM_STAT_QUERY;

		cmdToSend |= CMD_BIT(FPP_CMD_STAT_CONNECTION);
	}
        else if(strcasecmp(keywords[cpt], "pppoe") == 0)
	{
		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "query") == 0) 
		{
			pppoeStatusCmd.action = FPP_CMM_STAT_QUERY;
		}
		else if(strcasecmp(keywords[cpt], "query_reset") == 0) 
		{
			pppoeStatusCmd.action = FPP_CMM_STAT_QUERY_RESET;
 		}
		else
			goto keyword_error;

 		cmdToSend |= CMD_BIT(FPP_CMD_STAT_PPPOE_STATUS);
	}
	else if(strcasecmp(keywords[cpt], "bridge") == 0)
	{
		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "query") == 0) 
		{
			bridgeStatusCmd.action = FPP_CMM_STAT_QUERY;
		}
		else if(strcasecmp(keywords[cpt], "query_reset") == 0) 
		{
			bridgeStatusCmd.action = FPP_CMM_STAT_QUERY_RESET;
 		}
		else
			goto keyword_error;

 		cmdToSend |= CMD_BIT(FPP_CMD_STAT_BRIDGE_STATUS);
	}
	else if(strcasecmp(keywords[cpt], "ipsec") == 0)
	{
		if(!keywords[++cpt])
			goto help;

 		if((strcasecmp(keywords[cpt], "query") == 0) || (strcasecmp(keywords[cpt], "query_reset") == 0)) {
			if(strcasecmp(keywords[cpt], "query") == 0) 
			{
				ipsecStatusCmd.action = FPP_CMM_STAT_QUERY;
			}
			else if(strcasecmp(keywords[cpt], "query_reset") == 0) 
			{
				ipsecStatusCmd.action = FPP_CMM_STAT_QUERY_RESET;
	 		}
			else
				goto keyword_error;

			cmdToSend |= CMD_BIT(FPP_CMD_STAT_IPSEC_STATUS);
		}
		else
		 	goto help;
	}
	else if(strcasecmp(keywords[cpt], "vlan") == 0)
	{
		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "query") == 0) 
		{
			vlanStatusCmd.action = FPP_CMM_STAT_QUERY;
		}
		else if(strcasecmp(keywords[cpt], "query_reset") == 0) 
		{
			vlanStatusCmd.action = FPP_CMM_STAT_QUERY_RESET;
 		}
		else
			goto keyword_error;

 		cmdToSend |= CMD_BIT(FPP_CMD_STAT_VLAN_STATUS);
	}	
	else if(strcasecmp(keywords[cpt], "tunnel") == 0)
	{
		if(!keywords[++cpt])
			goto help;

		memset(&tunnelStatusCmd, 0, sizeof(tunnelStatusCmd));
		if(strcasecmp(keywords[cpt], "name") == 0)
		{
			if(!keywords[++cpt])
				goto help;
			strncpy(tunnelStatusCmd.if_name, keywords[cpt], sizeof(tunnelStatusCmd.if_name) - 1);
			if(!keywords[++cpt])
				goto help;
		}
		if(strcasecmp(keywords[cpt], "query") == 0)
		{
			tunnelStatusCmd.action = FPP_CMM_STAT_QUERY;
		}
		else if(strcasecmp(keywords[cpt], "query_reset") == 0)
		{
			tunnelStatusCmd.action = FPP_CMM_STAT_QUERY_RESET;
		}
		else
			goto keyword_error;

		cmdToSend |= CMD_BIT(FPP_CMD_STAT_TUNNEL_STATUS);
	}
	else
		goto keyword_error;

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_QUEUE))
	{
		/* Send CMD_STAT_QUEUE command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_QUEUE, & queueShowCmd, sizeof(queueShowCmd), rcvBuffer);

		if ( rcvBytes != sizeof(fpp_stat_queue_response_t))
		{
			cmm_print(DEBUG_STDERR, "ERROR: Unexpected returned result from FPP rc:%04x\n",
						  (rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer));
  			goto exit;
                }
		else
		{
			queueStatRsp = (fpp_stat_queue_response_t *)(rcvBuffer);
			cmm_print(DEBUG_STDOUT, "Emitted Pkts: 0x%0x \n" "Dropped Packets: 0x%0x\n" "Peak Queue Occupancy: 0x%0x \n",
						queueStatRsp->emitted_pkts, queueStatRsp->dropped_pkts, queueStatRsp->peak_queue_occ);
		}
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_INTERFACE_PKT))
	{
		/* Send CMD_STAT_INTERFACE_PKT command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_INTERFACE_PKT, & interfaceShowCmd, sizeof(interfaceShowCmd), rcvBuffer);

		if ( rcvBytes != sizeof(fpp_stat_interface_pkt_response_t)  )
		{
			cmm_print(DEBUG_STDERR, "ERROR: Unexpected returned result from FPP rc:%04x\n",
					  (rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer));
			goto exit;
		}
		else
		{
			interfacePktStatRsp = (fpp_stat_interface_pkt_response_t *)(rcvBuffer);

			total_bytes_transmitted_0 = interfacePktStatRsp->total_bytes_transmitted[0];
			total_bytes_transmitted_1 = interfacePktStatRsp->total_bytes_transmitted[1];
			total_bytes_transmitted_1 <<= 32;

			total_bytes_transmitted = total_bytes_transmitted_0 | total_bytes_transmitted_1;

			total_bytes_received_0 = interfacePktStatRsp->total_bytes_received[0];
			total_bytes_received_1 = interfacePktStatRsp->total_bytes_received[1];
			total_bytes_received_1 <<= 32;

			total_bytes_received = total_bytes_received_0 | total_bytes_received_1;


			cmm_print(DEBUG_STDOUT, "Total Bytes Received: %llu \n"
						"Total Bytes Transmitted: %llu \n"
						"Total Packets Received: %u \n"
						"Total Packets Transmitted: %u \n",
						total_bytes_received, total_bytes_transmitted, 
						interfacePktStatRsp->total_pkts_received, interfacePktStatRsp->total_pkts_transmitted);
		}
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_CONNECTION))
	{
		/* Send CMD_STAT_CONNECTION command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_CONNECTION, & connShowCmd, sizeof(connShowCmd), rcvBuffer);

		if ( rcvBytes != sizeof(fpp_stat_conn_response_t) )
		{
			cmm_print(DEBUG_STDERR, "ERROR: Unexpected returned result from FPP rc:%04x\n",
					  (rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer));
  			goto exit;
		}
		else
		{
			connStatRsp = (fpp_stat_conn_response_t *)(rcvBuffer);
#if !defined(COMCERTO_2000)
			cmm_print(DEBUG_STDOUT, "Maximum Active Connections: %u \n"
						"Number of Active Connections: %u \n",
				connStatRsp->max_active_connections, connStatRsp->num_active_connections);
#else
			cmm_print(DEBUG_STDOUT, "Maximum connections supported in FE: %u \n"
						"Maximum Active Connections: %s \n"
						"Number of Active Connections: %u \n"
						"Configured FE DDR Memory available for connections: %s \n"
						"FE DDR Memory used by connections: %s \n",
				connStatRsp->max_active_connections,
				"N/A",
				connStatRsp->num_active_connections,
				"N/A",
				"N/A");
#endif
		}
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_PPPOE_STATUS))
	{
		int count = 0;
		char interface[IFNAMSIZ];
		fpp_stat_pppoe_entry_response_t *pEntryResponse = (fpp_stat_pppoe_entry_response_t *)rcvBuffer;
		/* Send CMD_STAT_PPPOE_STATUS command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_PPPOE_STATUS, &pppoeStatusCmd, sizeof(pppoeStatusCmd), rcvBuffer);
		if (rcvBytes != 2)
		{
			cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n",
				  (rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer)
			  );
			goto exit;
		}

		while (1)
		{
			rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_PPPOE_ENTRY, NULL, 0, rcvBuffer);
			if (rcvBytes != sizeof(fpp_stat_pppoe_entry_response_t))
			{
				cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n",
				  	(rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer)
			  	);
				goto exit;
			}
			if (pEntryResponse->eof)
			    	break;

			get_port_name(pEntryResponse->interface_no, interface, IFNAMSIZ);

			cmm_print(DEBUG_STDOUT, "Session ID = 0x%0x "
			                        "Interface=%-6s "
						"Packets Received = 0x%0x "
						"Packets Transmitted = 0x%0x\n",
						    pEntryResponse->sessionid,
						    interface,
						    pEntryResponse->total_packets_received,
						    pEntryResponse->total_packets_transmitted);
			count++;
		}
		cmm_print(DEBUG_STDOUT, "\n Statistics of %d PPPoE Sessions displayed \n", count);
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_BRIDGE_STATUS))
	{
		int count = 0;
		char input_interface[IFNAMSIZ];
		char output_interface[IFNAMSIZ];
		fpp_stat_bridge_entry_response_t *pEntryResponse = (fpp_stat_bridge_entry_response_t *)rcvBuffer;
		/* Send CMD_STAT_BRIDGE_STATUS command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_BRIDGE_STATUS, &bridgeStatusCmd, sizeof(bridgeStatusCmd), rcvBuffer);
		if (rcvBytes != 2)
		{
			cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n",
				  (rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer)
			  );
			goto exit;
		}

		while (1)
		{
			rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_BRIDGE_ENTRY, NULL, 0, rcvBuffer);
			if (rcvBytes != sizeof(fpp_stat_bridge_entry_response_t))
			{
				cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n",
				  	(rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer)
			  	);
				goto exit;
			}
			if (pEntryResponse->eof)
			    	break;

			if (pEntryResponse->input_interface >= GEM_PORTS)
				strcpy(input_interface, pEntryResponse->input_name);
			else
				get_port_name(pEntryResponse->input_interface, input_interface, IFNAMSIZ);

			if ((pEntryResponse->input_svlan != 0xFFFF) && (pEntryResponse->input_cvlan != 0xFFFF))
				sprintf(input_interface + strlen(input_interface), ".%d.%d", pEntryResponse->input_svlan, pEntryResponse->input_cvlan);
			else if (pEntryResponse->input_svlan != 0xFFFF)
				sprintf(input_interface + strlen(input_interface), ".%d", pEntryResponse->input_svlan);

			if (pEntryResponse->output_interface >= GEM_PORTS)
				strcpy(output_interface, pEntryResponse->output_name);	
			else	
				get_port_name(pEntryResponse->output_interface, output_interface, IFNAMSIZ);

			if ((pEntryResponse->output_svlan != 0xFFFF) && (pEntryResponse->output_cvlan != 0xFFFF))
				sprintf(output_interface + strlen(output_interface), ".%d.%d", pEntryResponse->output_svlan, pEntryResponse->output_cvlan);
			else if (pEntryResponse->output_svlan != 0xFFFF)
				sprintf(output_interface + strlen(output_interface), ".%d", pEntryResponse->output_svlan);

			cmm_print(DEBUG_STDOUT, "Input=%-6s "
				                "DA=%02X:%02X:%02X:%02X:%02X:%02X "
				                "SA=%02X:%02X:%02X:%02X:%02X:%02X "
						"Type=%04X "
						"Output=%s "
						"SessionId=%d "
						"Packets Transmitted = 0x%0x\n",
						    input_interface,
						    pEntryResponse->dst_mac[0], pEntryResponse->dst_mac[1], pEntryResponse->dst_mac[2],
						    pEntryResponse->dst_mac[3], pEntryResponse->dst_mac[4], pEntryResponse->dst_mac[5],
						    pEntryResponse->src_mac[0], pEntryResponse->src_mac[1], pEntryResponse->src_mac[2],
						    pEntryResponse->src_mac[3], pEntryResponse->src_mac[4], pEntryResponse->src_mac[5],
						    pEntryResponse->ether_type, output_interface,pEntryResponse->session_id,
						    pEntryResponse->total_packets_transmitted);
			count++;
		}
		cmm_print(DEBUG_STDOUT, "\n Statistics of %d Bridge Table Entries displayed \n", count);
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_IPSEC_STATUS))
	{
		int count = 0;
		fpp_stat_ipsec_entry_response_t *pEntryResponse = (fpp_stat_ipsec_entry_response_t *)rcvBuffer;
		/* Send CMD_STAT_IPSEC_STATUS command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_IPSEC_STATUS, &ipsecStatusCmd, sizeof(ipsecStatusCmd), rcvBuffer);
		if (rcvBytes != 2)
		{
			cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n",
				  (rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer)
			  );
			goto exit;
		}

		while (1)
		{
			rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_IPSEC_ENTRY, NULL, 0, rcvBuffer);
			if (rcvBytes != sizeof(fpp_stat_ipsec_entry_response_t))
			{
				cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n",
				  	(rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer)
			  	);
				goto exit;
			}
			if (pEntryResponse->eof)
			    	break;

			total_bytes_transmitted_0 = pEntryResponse->total_bytes_processed[0];
			total_bytes_transmitted_1 = pEntryResponse->total_bytes_processed[1];
			total_bytes_transmitted_1 <<= 32;

			total_bytes_transmitted = total_bytes_transmitted_0 | total_bytes_transmitted_1;

			cmm_print(DEBUG_STDOUT, "\nSPI: %x \n",  pEntryResponse->spi);
			if(pEntryResponse->family == FPP_PROTO_IPV4){
				cmm_print(DEBUG_STDOUT, "Dst IP: %d.%d.%d.%d \n", (pEntryResponse->dst_ip[0] & 0x000000ff), 
						    				((pEntryResponse->dst_ip[0] >> 8) & 0x000000ff),
						    				((pEntryResponse->dst_ip[0] >> 16) & 0x000000ff),
						    				((pEntryResponse->dst_ip[0] >> 24) & 0x000000ff));
			}
			else{
				char addr[64];
			
				inet_ntop(AF_INET6, pEntryResponse->dst_ip, addr, sizeof(addr));
				cmm_print(DEBUG_STDOUT,"Dst IP: %s\n", addr);
			}
			cmm_print(DEBUG_STDOUT, "IPsec proto: %d \n",  pEntryResponse->proto);
			cmm_print(DEBUG_STDOUT, "Total Packets Processed: %u \n"
						"Total Bytes Processed: %llu \n \n",
						 pEntryResponse->total_pkts_processed, total_bytes_transmitted);
			count++;
		}
		cmm_print(DEBUG_STDOUT, "\n Statistics of %d SA Entries displayed \n", count);
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_VLAN_STATUS))
	{
		int count = 0;
		fpp_stat_vlan_entry_response_t *pEntryResponse = (fpp_stat_vlan_entry_response_t *)rcvBuffer;
		/* Send FPP_CMD_STAT_VLAN_STATUS command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_VLAN_STATUS, &vlanStatusCmd, sizeof(vlanStatusCmd), rcvBuffer);
		if (rcvBytes != 2)
		{
			cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n",
				  (rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer)
			  );
			goto exit;
		}

		while (1)
		{
			rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_VLAN_ENTRY, NULL, 0, rcvBuffer);
			if (rcvBytes != sizeof(fpp_stat_vlan_entry_response_t))
			{
				cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n",
				  	(rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer)
			  	);
				goto exit;
			}
			if (pEntryResponse->eof)
			    	break;

			total_bytes_transmitted_0 = pEntryResponse->total_bytes_transmitted[0];
			total_bytes_transmitted_1 = pEntryResponse->total_bytes_transmitted[1];
			total_bytes_transmitted_1 <<= 32;

			total_bytes_transmitted = total_bytes_transmitted_0 | total_bytes_transmitted_1;

			total_bytes_received_0 = pEntryResponse->total_bytes_received[0];
			total_bytes_received_1 = pEntryResponse->total_bytes_received[1];
			total_bytes_received_1 <<= 32;

			total_bytes_received = total_bytes_received_0 | total_bytes_received_1;
			
			cmm_print(DEBUG_STDOUT, "VLAN ID = %4d "
			                        "VLAN Interface Name = %s "
			                        "VLAN Physical Interface Name = %s "			                        
						"Packets Received = %u "
						"Packets Transmitted = %u "
						"Bytes Received = %llu "
						"Bytes Transmitted = %llu\n",
						    pEntryResponse->vlanID,
						    pEntryResponse->vlanifname,
						    pEntryResponse->phyifname,						    
						    pEntryResponse->total_packets_received,
						    pEntryResponse->total_packets_transmitted, total_bytes_received, total_bytes_transmitted);

			count++;
		}
		cmm_print(DEBUG_STDOUT, "\n Statistics of %d VLAN Entries displayed \n", count);
	}
	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_TUNNEL_STATUS))
	{
		int count = 0;
		fpp_stat_tunnel_entry_response_t *pEntryResponse = (fpp_stat_tunnel_entry_response_t *)rcvBuffer;
		/* Send FPP_CMD_STAT_TUNNEL_STATUS command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_TUNNEL_STATUS, &tunnelStatusCmd, sizeof(tunnelStatusCmd), rcvBuffer);
		if (rcvBytes != 2)
		{
			cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n",
				  (rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer)
			  );
			goto exit;
		}

		while (1)
		{
			rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_TUNNEL_ENTRY, NULL, 0, rcvBuffer);
			if (rcvBytes != sizeof(fpp_stat_tunnel_entry_response_t))
			{
				cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n",
					(rcvBytes < sizeof(unsigned short) ) ? 0 : *((unsigned short *) rcvBuffer));
				goto exit;
			}
			if (pEntryResponse->eof)
				break;

			total_bytes_transmitted_0 = pEntryResponse->total_bytes_transmitted[0];
			total_bytes_transmitted_1 = pEntryResponse->total_bytes_transmitted[1];
			total_bytes_transmitted_1 <<= 32;

			total_bytes_transmitted = total_bytes_transmitted_0 | total_bytes_transmitted_1;

			total_bytes_received_0 = pEntryResponse->total_bytes_received[0];
			total_bytes_received_1 = pEntryResponse->total_bytes_received[1];
			total_bytes_received_1 <<= 32;

			total_bytes_received = total_bytes_received_0 | total_bytes_received_1;

			cmm_print(DEBUG_STDOUT, "Tunnel Name = %s, "
						"Packets Received = %u, "
						"Packets Transmitted = %u, "
						"Bytes Received = %llu, "
						"Bytes Transmitted = %llu\n",
						    pEntryResponse->if_name,
						    pEntryResponse->total_packets_received,
						    pEntryResponse->total_packets_transmitted, total_bytes_received, total_bytes_transmitted);

			count++;
		}
		if (count > 1)
			cmm_print(DEBUG_STDOUT, "\n Statistics of %d Tunnel Entries displayed \n", count);
	}


	return 0;

keyword_error:
	cmm_print(DEBUG_STDERR, "ERROR: Unknown keyword %s\n", keywords[cpt]);

help:
	cmmStatShowPrintHelp();

exit:
	return -1;

}


/************************************************************
 *
 *
 *
 ************************************************************/
void cmmStatSetPrintHelp(int cmd_type)
{
	if (cmd_type == FPP_STAT_UNKNOWN_CMD || cmd_type == FPP_STAT_ENABLE_CMD)
	{
	    cmm_print(DEBUG_STDOUT, "Usage: set stat enable {queue|interface|vlan|pppoe|bridge|ipsec|tunnel}\n"
		                     "      set stat disable {queue|interface|vlan|pppoe|bridge|ipsec|tunnel}\n");
	}
	if (cmd_type == FPP_STAT_UNKNOWN_CMD || cmd_type == FPP_STAT_QUEUE_CMD)
	{
	    cmm_print(DEBUG_STDOUT, 
                      "Usage: set stat queue {queue_no} interface {wan|lan|wan0|lan0} reset \n");
      	}
	if (cmd_type == FPP_STAT_UNKNOWN_CMD || cmd_type == FPP_STAT_INTERFACE_PKT_CMD)
	{
	    cmm_print(DEBUG_STDOUT, 
                      "Usage: set stat interface {wan|lan|wan0|lan0} reset\n");
      	}
	if (cmd_type == FPP_STAT_UNKNOWN_CMD || cmd_type == FPP_STAT_VLAN_CMD)
	{
	    cmm_print(DEBUG_STDOUT, 
                  "Usage: set stat vlan reset\n");
	}      	
	if (cmd_type == FPP_STAT_UNKNOWN_CMD || cmd_type == FPP_STAT_PPPOE_CMD)
	{
	    cmm_print(DEBUG_STDOUT, 
                  "Usage: set stat pppoe reset\n");
	}
	if (cmd_type == FPP_STAT_UNKNOWN_CMD || cmd_type == FPP_STAT_BRIDGE_CMD)
	{
	    cmm_print(DEBUG_STDOUT, 
                  "Usage: set stat bridge reset\n");
	}
	if (cmd_type == FPP_STAT_UNKNOWN_CMD || cmd_type == FPP_STAT_IPSEC_CMD)
	{
	    cmm_print(DEBUG_STDOUT, 
                  "Usage: set stat ipsec reset\n");
	}
	if (cmd_type == FPP_STAT_UNKNOWN_CMD || cmd_type == FPP_STAT_TUNNEL_CMD)
	{
	    cmm_print(DEBUG_STDOUT, "Usage: set stat tunnel reset\n");
	}
	if (cmd_type == FPP_STAT_UNKNOWN_CMD || cmd_type == FPP_STAT_CONNECTION_CMD)
	{
	    cmm_print(DEBUG_STDOUT, "Usage: set stat connection { maxconn <no.of connections> } \n"
				    "                           { memconn <Value of FPP DDR memory available for connections specified in bytes> }\n");
	}

	if (cmd_type == FPP_STAT_UNKNOWN_CMD)
	{
	    cmm_print(DEBUG_STDOUT, "\n");
	}

}


/************************************************************
 *
 *
 *
 ************************************************************/
int cmmStatSetProcess(char ** keywords, int tabStart, daemon_handle_t daemon_handle)
{
	int cmd_type = FPP_STAT_UNKNOWN_CMD;
	int cpt = tabStart;
	unsigned int cmdToSend = 0; /* bits field*/
	char * endptr;
	unsigned int tmp;
        int rcvBytes = 0;
	char *pinterface;
	unsigned short interface;


	fpp_stat_enable_cmd_t statEnableCmd;
	fpp_stat_queue_cmd_t queueResetCmd;  
	fpp_stat_interface_cmd_t interfaceResetCmd;
	fpp_stat_pppoe_status_cmd_t pppoeResetCmd;
	fpp_stat_bridge_status_cmd_t bridgeResetCmd;
	fpp_stat_ipsec_status_cmd_t ipsecResetCmd;
	fpp_stat_vlan_status_cmd_t vlanResetCmd;
	fpp_stat_tunnel_status_cmd_t tunnelResetCmd;

	char rcvBuffer[256];

	if(!keywords[cpt])
		goto help;

	if( (strcasecmp(keywords[cpt], "enable") == 0) ||
	    (strcasecmp(keywords[cpt], "disable") == 0) )
	{
		cmd_type = FPP_STAT_ENABLE_CMD;

		if(strcasecmp(keywords[cpt], "enable") == 0)
			statEnableCmd.action = FPP_CMM_STAT_ENABLE;
		else
			statEnableCmd.action = FPP_CMM_STAT_DISABLE;

		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "queue") == 0)
			statEnableCmd.bitmask = FPP_STAT_QUEUE_BITMASK;
		else if(strcasecmp(keywords[cpt], "interface") == 0)
			statEnableCmd.bitmask = FPP_STAT_INTERFACE_BITMASK;
		else if(strcasecmp(keywords[cpt], "pppoe") == 0)
			statEnableCmd.bitmask = FPP_STAT_PPPOE_BITMASK;
		else if(strcasecmp(keywords[cpt], "bridge") == 0)
			statEnableCmd.bitmask = FPP_STAT_BRIDGE_BITMASK;
		else if(strcasecmp(keywords[cpt], "ipsec") == 0)
			statEnableCmd.bitmask = FPP_STAT_IPSEC_BITMASK;
		else if(strcasecmp(keywords[cpt], "vlan") == 0)
			statEnableCmd.bitmask = FPP_STAT_VLAN_BITMASK;			
		else if(strcasecmp(keywords[cpt], "tunnel") == 0)
			statEnableCmd.bitmask = FPP_STAT_TUNNEL_BITMASK;
		else
			goto keyword_error;

		cmdToSend |= CMD_BIT(FPP_CMD_STAT_ENABLE);
	
	}
	else if(strcasecmp(keywords[cpt], "queue") == 0)
	{
		cmd_type = FPP_STAT_QUEUE_CMD;
		if(!keywords[++cpt])
			goto help;

		/*Get an integer from the string*/
		endptr = NULL;
		tmp = strtoul(keywords[cpt], &endptr, 0);
		if ((keywords[cpt] == endptr) || (tmp >= FPP_NUM_QUEUES))
		{
			cmm_print(DEBUG_CRIT, "Stat ERROR: Queue Number must be a number between 0 and %d\n", FPP_NUM_QUEUES - 1);
			goto help;
		}

		memset(&queueResetCmd, 0, sizeof(queueResetCmd));
		queueResetCmd.queue= tmp;

		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "interface") != 0)
			goto keyword_error;

		if(!keywords[++cpt])
			goto help;

		pinterface = keywords[cpt];
		if (parse_interface(pinterface, &interface) < 0)
			goto help;

		queueResetCmd.interface = interface;

		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "reset") != 0)
			goto help;

		queueResetCmd.action = FPP_CMM_STAT_RESET;
		cmdToSend |= CMD_BIT(FPP_CMD_STAT_QUEUE);
	}
	else if(strcasecmp(keywords[cpt], "interface") == 0)
	{
		cmd_type = FPP_STAT_INTERFACE_PKT_CMD;
		if(!keywords[++cpt])
			goto help;
		pinterface = keywords[cpt];

		memset(&interfaceResetCmd, 0, sizeof(interfaceResetCmd));
		if (parse_interface(pinterface, &interface) < 0)
			goto help;

		interfaceResetCmd.interface = interface;

		if(!keywords[++cpt])
			goto help;


		if(strcasecmp(keywords[cpt], "reset") != 0)
				goto help;

		interfaceResetCmd.action = FPP_CMM_STAT_RESET;
		cmdToSend |= CMD_BIT(FPP_CMD_STAT_INTERFACE_PKT);
	}
	else if(strcasecmp(keywords[cpt], "pppoe") == 0)
	{
		cmd_type = FPP_STAT_PPPOE_CMD;
		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "reset") != 0)
			goto help;

		pppoeResetCmd.action = FPP_CMM_STAT_RESET;
		cmdToSend |= CMD_BIT(FPP_CMD_STAT_PPPOE_STATUS);
	}
	else if(strcasecmp(keywords[cpt], "bridge") == 0)
	{
		cmd_type = FPP_STAT_BRIDGE_CMD;
		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "reset") != 0)
			goto help;

		bridgeResetCmd.action = FPP_CMM_STAT_RESET;
		cmdToSend |= CMD_BIT(FPP_CMD_STAT_BRIDGE_STATUS);
	}
	else if(strcasecmp(keywords[cpt], "ipsec") == 0)
	{
		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "reset") == 0) 
		{
			cmd_type = FPP_STAT_IPSEC_CMD;

			ipsecResetCmd.action = FPP_CMM_STAT_RESET;
			cmdToSend |= CMD_BIT(FPP_CMD_STAT_IPSEC_STATUS);

		}
		else
			goto help;
	}
	else if(strcasecmp(keywords[cpt], "vlan") == 0)
	{
		cmd_type = FPP_STAT_VLAN_CMD;
		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "reset") != 0)
			goto help;

		vlanResetCmd.action = FPP_CMM_STAT_RESET;
		cmdToSend |= CMD_BIT(FPP_CMD_STAT_VLAN_STATUS);
	}		
	else if(strcasecmp(keywords[cpt], "tunnel") == 0)
	{
		cmd_type = FPP_STAT_TUNNEL_CMD;
		if(!keywords[++cpt])
			goto help;

		if(strcasecmp(keywords[cpt], "reset") != 0)
			goto help;

		tunnelResetCmd.action = FPP_CMM_STAT_RESET;
		cmdToSend |= CMD_BIT(FPP_CMD_STAT_TUNNEL_STATUS);
	}
	else if(strcasecmp(keywords[cpt], "connection") == 0)
	{
		if(!keywords[++cpt])
			goto help;
		if((strcasecmp(keywords[cpt], "maxconn") != 0) &&
			(strcasecmp(keywords[cpt], "memconn") != 0) )
			goto help;
		if(strcasecmp(keywords[cpt], "maxconn") == 0)
		{
			if(!keywords[++cpt])
				goto help;

			tmp = strtoul(keywords[cpt], &endptr, 0);
		}
		else if ( strcasecmp(keywords[cpt], "memconn") == 0 )
		{
			if(!keywords[++cpt])
				goto help;

			tmp = strtoul(keywords[cpt], &endptr, 0);
		}
		/* Just Positively acknowledge the command & return without programming FE */
		goto ack_return;
	}
	else
		goto keyword_error;


	/*
	 * Parsing have been performed
	 * Now send the right commands
	 */
	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_ENABLE))
	{
		/* Send CMD_STAT_ENABLE command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_ENABLE, &statEnableCmd, sizeof(statEnableCmd), rcvBuffer);
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_QUEUE))
	{
		/* Send CMD_STAT_QUEUE command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_QUEUE, &queueResetCmd, sizeof(queueResetCmd), rcvBuffer);
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_INTERFACE_PKT))
	{
		/* Send CMD_STAT_INTERFACE_PKT command */
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_INTERFACE_PKT, &interfaceResetCmd, sizeof(interfaceResetCmd), rcvBuffer);
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_PPPOE_STATUS))
	{
		// Send CMD_STAT_PPPOE_STATUS command
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_PPPOE_STATUS, &pppoeResetCmd, sizeof(pppoeResetCmd), rcvBuffer);
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_BRIDGE_STATUS))
	{
		// Send CMD_STAT_BRIDGE_STATUS command
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_BRIDGE_STATUS, &bridgeResetCmd, sizeof(bridgeResetCmd), rcvBuffer);
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_IPSEC_STATUS))
        {
                /* Send CMD_STAT_IPSEC_STATUS command */
                 rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_IPSEC_STATUS, &ipsecResetCmd, sizeof(ipsecResetCmd), rcvBuffer);
        }

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_VLAN_STATUS))
	{
		// Send FPP_CMD_STAT_VLAN_STATUS command
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_VLAN_STATUS, &vlanResetCmd, sizeof(vlanResetCmd), rcvBuffer);
	}

	if(TEST_CMD_BIT(cmdToSend, FPP_CMD_STAT_TUNNEL_STATUS))
	{
		// Send FPP_CMD_STAT_TUNNEL_STATUS command
		rcvBytes = cmmSendToDaemon(daemon_handle, FPP_CMD_STAT_TUNNEL_STATUS, &tunnelResetCmd, sizeof(tunnelResetCmd), rcvBuffer);
	}

	if ( (rcvBytes == 2) && ( ((unsigned short *)rcvBuffer)[0] != 0))
	  cmm_print(DEBUG_STDERR, "ERROR: Unexpected result returned from FPP rc:%04x\n", ((unsigned short *)rcvBuffer)[0]);        

ack_return:
	return 0;

keyword_error:
	cmm_print(DEBUG_CRIT, "ERROR: Unknown keyword %s\n", keywords[cpt]);

help:
	cmmStatSetPrintHelp(cmd_type);
	return -1;

}

static int parse_interface(char *pstring, unsigned short *pinterface_number)
{
	if ((short)(*pinterface_number = get_port_id(pstring)) < 0)
	{
		/*cmm_print(DEBUG_CRIT, "ERROR: Invalid interface specification: %s\n", pstring);*/
		return -1;
	}
	return 0;
}

