#include "main.h"
#include <stdio.h>
#include <stdint.h>
#include <sys/prctl.h>
#include <semaphore.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>

#include "main.h"
#include "ChassisTimerTask.h"
#include "ChassisDevice.h"
#include "com_IPMI_Chassis.h"
#include "com_IPMI_LANConfig.h"
#include "com_IPMI_DeviceConfig.h"
#include "SensorMonitor.h"
#include "time.h"
#include "com_IPMI_Storlead.h"

#include "com_IPMI_App.h"
#include "hal_interface_api.h"
#include "Api.h"

int 		gPendActionIfc;

void *PendActionTask(void *Param)
{
	MsgPkt_T	MsgPkt;
	char  		cmdStr[100] = {0};
	SetLanConfigReq_T  *pSetLanCfg;
	prctl(PR_SET_NAME,__FUNCTION__,0,0,0);

	printf("PendActionTask Started... \n");

	//create 
    if(-1 != access(PEND_ACTION_HNDLR_Q, F_OK))
    {
        remove(PEND_ACTION_HNDLR_Q);
    }
    if(0 != mkfifo (PEND_ACTION_HNDLR_Q, 0777))
    {
        printf("%s: Create %s fifo failed! %s\n", __FUNCTION__, PEND_ACTION_HNDLR_Q, strerror(errno));
        return (void*)-1;
    }
    gPendActionIfc = open (PEND_ACTION_HNDLR_Q, O_RDWR);
    if(-1 == gPendActionIfc)
    {
        printf("%s: Open %s fifo failed! %s\n", __FUNCTION__, PEND_ACTION_HNDLR_Q, strerror(errno));
        return (void*)-1;
    }

    while(1)
    {
		if(GetMsg(gPendActionIfc, &MsgPkt,  WAIT_INFINITE) == 0)
		{
			if(MsgPkt.Param == PARAM_CHASSIS)
			{
				//Chassis power control
				if((NET_FN(MsgPkt.NetFnLUN) == NETFN_CHASSIS) && (MsgPkt.Cmd == CMD_CHASSIS_CONTROL))
				{
					switch(MsgPkt.Data[0])
					{
						case CHASSIS_POWER_DOWN:
							PDK_PowerOffChassis();
							break;
						case CHASSIS_POWER_UP:
							PDK_PowerOnChassis();
							break;
						case CHASSIS_POWER_CYCLE:
							PDK_PowerCycleChassis();
							break;
						case CHASSIS_HARD_RESET:
							PDK_ResetChassis();
							break;
						case CHASSIS_PULSE_DIAGNOSTIC_INTERRUPT:
							PDK_DiagInterruptChassis();
							break;
						case CHASSIS_SOFT_SHUTDOWN:
							PDK_SoftOffChassis();
							break;
						default:
							printf("Invalid power control cmd\r\n");
							break;
					}
				}
			}
			else if(MsgPkt.Param == PARAM_MC)
			{
				if(((MsgPkt.NetFnLUN>>2) == NETFN_APP) && (MsgPkt.Cmd == CMD_COLD_RESET)) 
				{
					sleep(1);	//wait ipmi request response finish.
					pthread_mutex_lock(&Flash_Mutex);
					stm32_reset_mcu();
					pthread_mutex_unlock(&Flash_Mutex);
				}
				else if(((MsgPkt.NetFnLUN>>2) == NETFN_APP) && (MsgPkt.Cmd == CMD_WARM_RESET))
				{
					sleep(1);	//wait ipmi request response finish.
					pthread_mutex_lock(&Flash_Mutex);
					sprintf(cmdStr, "reboot");
					system(cmdStr);
					pthread_mutex_unlock(&Flash_Mutex);
				} 
			}
			else if(MsgPkt.Param == PARAM_LAN)
			{
				pSetLanCfg = (SetLanConfigReq_T*)MsgPkt.Data;
				printf("---> PARAM_LAN, NetFnLUN: %#x, cmd: %#x\n", MsgPkt.NetFnLUN, MsgPkt.Cmd);
				printf("---> Data: %#x %#x %#x %#x %#x\n", MsgPkt.Data[0], MsgPkt.Data[1], MsgPkt.Data[2], MsgPkt.Data[3], MsgPkt.Data[4]);
				if(((MsgPkt.NetFnLUN>>2) == NETFN_TRANSPORT) 
					&& (MsgPkt.Cmd == CMD_SET_LAN_CONFIGURATION_PARAMETERS)
					&& (pSetLanCfg->ChannelNum == LAN_RMCP_CHANNEL)) 
				{
					//Modify IP
					if(pSetLanCfg->ParameterSelect == LAN_PARAM_IP_ADDRESS)
					{
						
						sprintf(cmdStr, "ifconfig eth0 %d.%d.%d.%d up", 
							pSetLanCfg->ConfigData.IPAddr[0], pSetLanCfg->ConfigData.IPAddr[1],
							pSetLanCfg->ConfigData.IPAddr[2], pSetLanCfg->ConfigData.IPAddr[3]);
						printf("Execute cmd: %s\n", cmdStr);
						sleep(1);
						system(cmdStr);
					}
					else if(pSetLanCfg->ParameterSelect == LAN_PARAM_MAC_ADDRESS)
					{
						sprintf(cmdStr, "ifconfig eth0 hw ether %02x:%02x:%02x:%02x:%02x:%02x", 
							pSetLanCfg->ConfigData.MACAddr[0], pSetLanCfg->ConfigData.MACAddr[1],
							pSetLanCfg->ConfigData.MACAddr[2], pSetLanCfg->ConfigData.MACAddr[3],
							pSetLanCfg->ConfigData.MACAddr[4], pSetLanCfg->ConfigData.MACAddr[5]);
						printf("Execute cmd: %s\n", cmdStr);
						sleep(1);
						system("ifconfig eth0 down");						
						system(cmdStr);
						system("ifconfig eth0 up");
					}
					else if(pSetLanCfg->ParameterSelect == LAN_PARAM_SUBNET_MASK)
					{
						sprintf(cmdStr, "ifconfig eth0 netmask %d.%d.%d.%d", 
							pSetLanCfg->ConfigData.SubNetMask[0], pSetLanCfg->ConfigData.SubNetMask[1],
							pSetLanCfg->ConfigData.SubNetMask[2], pSetLanCfg->ConfigData.SubNetMask[3]);
						printf("Execute cmd: %s\n", cmdStr);
						sleep(1);
						system(cmdStr);
					}
					else if(pSetLanCfg->ParameterSelect == LAN_PARAM_DEFAULT_GATEWAY_IP)
					{
						sprintf(cmdStr, "route add default gw %d.%d.%d.%d", 
							pSetLanCfg->ConfigData.DefaultGatewayIPAddr[0], pSetLanCfg->ConfigData.DefaultGatewayIPAddr[1],
							pSetLanCfg->ConfigData.DefaultGatewayIPAddr[2], pSetLanCfg->ConfigData.DefaultGatewayIPAddr[3]);
						printf("Execute cmd: %s\n", cmdStr);
						sleep(1);
						system(cmdStr);
					}

				}
				else if(((MsgPkt.NetFnLUN>>2) == NETFN_STORLEAD) 
					&& (MsgPkt.Cmd == CMD_SET_LAN_INFO))
				{
					LanInfo_T *pSetLanInfo = (LanInfo_T*)MsgPkt.Data;
					sleep(1);
					//down
					sprintf(cmdStr, "ifconfig %s down", pSetLanInfo->EthName);
					printf("%s\n", cmdStr);
					system(cmdStr);
					//set mac
					sprintf(cmdStr, "ifconfig %s hw ether %02x:%02x:%02x:%02x:%02x:%02x", 
						pSetLanInfo->EthName, pSetLanInfo->MACAddr[0], pSetLanInfo->MACAddr[1],
						pSetLanInfo->MACAddr[2], pSetLanInfo->MACAddr[3], 
						pSetLanInfo->MACAddr[4], pSetLanInfo->MACAddr[5]);
					printf("%s\n", cmdStr);
					system(cmdStr);
					//ip, broadcast, netmask
					sprintf(cmdStr, "ifconfig %s %d.%d.%d.%d broadcast %d.%d.%d.%d netmask %d.%d.%d.%d up",
						pSetLanInfo->EthName, pSetLanInfo->IPAddr[0], pSetLanInfo->IPAddr[1],
						pSetLanInfo->IPAddr[2], pSetLanInfo->IPAddr[3], pSetLanInfo->BroadCast[0],
						pSetLanInfo->BroadCast[1], pSetLanInfo->BroadCast[2], pSetLanInfo->BroadCast[3],
						pSetLanInfo->NetMask[0], pSetLanInfo->NetMask[1], pSetLanInfo->NetMask[2],
						pSetLanInfo->NetMask[3]);
					printf("%s\n", cmdStr);
					system(cmdStr);
					//default gw
					sprintf(cmdStr, "route add default gw %d.%d.%d.%d", pSetLanInfo->DefaultGW[0],
						pSetLanInfo->DefaultGW[1],pSetLanInfo->DefaultGW[2],pSetLanInfo->DefaultGW[3]);
					printf("%s\n", cmdStr);
					system(cmdStr);
				} 
			}
		}
	}
}