#include <stdio.h>
#include <stdint.h>
#include "pthread.h"
#include "errno.h"
#include "bmc_main.h"
#include "bmc_conf.h"
#include "bmc_type.h"
#include "sensor_thread.h"
#include "power_thread.h"
#include "ipmb_thread.h"
#include "timer_thread.h"
#include "fcntl.h"

#include "./../stm32f429xx.h"
#include "./../driver/GPIO/gpio.h"
#include "platform.h"
#include "./../driver/I2C/i2c.h"
#include "i2c_api.h"
#include "spi_api.h"
#include "gpio_api.h"
#include "./lan/udp_api/udp.h"
#include "./test.h"
#include <semaphore.h>
#include "./lan/lanTask.h"
#include <stdlib.h>
#include "MsgHndlr.h"
#include "sensor_sdr_init.h"

#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>


pthread_t	gthreadIDs[MAX_THREAD]={0};
int 		gthreadIndex = 0;

BMCInfo_t 	g_BMCInfo;

char		SessionSequenceNumberCount=0;

/* mutex */
pthread_mutex_t 	sensorSdr_mutex;	//when modify sdr
pthread_mutex_t		powerSta_mutex;

sem_t sem_QUEUE;

IPMIQueue_T g_IPMIIfcQueue[MAX_IPMI_IFCQ];

int InitBMCSharedMem (void);


int InitBmcInfo(void);

#define SERVER_PORT 7897
#define BACKLOG     10

/*
 * The bmc main function.
 * All threads are created in here.
 * Author: Jimbo
 */
int main(int argc, char **argv)
{
	int iSocketServer;
	int iSocketClient;
	struct sockaddr_in tSocketServerAddr; //指定服务器绑定地址
	struct sockaddr_in tSocketClientAddr; //保存客户端地址
	int iRet;
	int iAddrLen;
	uint32_t recvCnt = 0;
				 
	int iRecvLen;
	unsigned char ucRecvBuf[2000];
	char sendBuf[1000] = {0};

	int iClientNum = -1;
										 
//	signal(SIGCHLD,SIG_IGN); //此函数用于处理僵尸进程
												
	iSocketServer = socket(AF_INET, SOCK_STREAM, 0);//AF_INET IPV4连接 SOCK_STREAM启动TCP连接
	if (-1 == iSocketServer)
	{
		printf("socket error!\n");
		return -1;
	}
										 
	tSocketServerAddr.sin_family      = AF_INET; //一般设置为
	tSocketServerAddr.sin_port        = htons(SERVER_PORT); //将SERVER_PORT转化为网络字节序 host to net, short
	tSocketServerAddr.sin_addr.s_addr = INADDR_ANY; //INADDR_ANY表示本机上所有IP
	memset(tSocketServerAddr.sin_zero, 0, 8);
																	 
																	 
	int opt = 1;  
	//使用setsockopt函数可以保证端口可被重复绑定
	iRet = setsockopt(iSocketServer, SOL_SOCKET,SO_REUSEADDR,(const void *)&opt, sizeof(opt) );	
	if (-1 == iRet)
	{
		printf("set sock option error!\n");
		close(iSocketServer);
		return -1;
	}
																	
																		
	iRet = bind(iSocketServer, (const struct sockaddr *)&tSocketServerAddr, sizeof(struct sockaddr)); //绑定端口
	if (-1 == iRet)
	{
		printf("bind error!\n");
		close(iSocketServer);
		return -1;
	}
							 
	iRet = listen(iSocketServer, BACKLOG); //设置监听 BACKLOG代表同时监听10路连接
	if (-1 == iRet)
	{
		printf("listen error!\n");
		return -1;
	}
	
	while (1)
	{
		iAddrLen = sizeof(struct sockaddr);
		iSocketClient = accept(iSocketServer, (struct sockaddr *)&tSocketClientAddr, &iAddrLen); //等待连接 如果建立连接
		if (-1 != iSocketClient)
		{
			iClientNum++;
			printf("Get connect from client %d : %s\n",  iClientNum, inet_ntoa(tSocketClientAddr.sin_addr));
			recvCnt = 0;
			while(1)
			{
				/* 接收客户端发来的数据并显示出来 */
				iRecvLen = recv(iSocketClient, ucRecvBuf, 2000, 0);
				if (iRecvLen <= 0)
				{
					printf("Recv count %d Byte!\n", recvCnt);
					close(iSocketClient); //关闭连接
					//return -1;
					break;
				}
				else
				{
					if(iRecvLen != 500)
						printf("Recv error: %d\n",iRecvLen);
					recvCnt += iRecvLen;
					//sprintf(sendBuf, "%d\n", recvCnt);
				//	ucRecvBuf[iRecvLen] = '\0';
				//	printf("Get Msg From Client %d: %s\n", iClientNum, ucRecvBuf);
					//send(iSocketClient, sendBuf, 11, 0);//打印的同时发送一条数据给连接的客户端
				}
			}
		}				
	}
	
	
	close(iSocketServer);
	return 0;
	


























/*
	if(sem_init(&sem_QUEUE, 0, 1) ==-1){
		printf("A lock for IPMI QUEUE is not created properly!!!\n");
	}
	system("ifconfig eth0 192.168.0.15");
//	platform_init();
	spi_api_read();	
	InitBmcInfo();
	sensor_sdr_init();
	memset(g_IPMIIfcQueue,0,(sizeof(IPMIQueue_T)*MAX_IPMI_IFCQ));
	InitBMCSharedMem ();
	//create fifo 
	{
		OS_CREATE_Q(OBSM_TASK_Q);
        	OS_GET_Q(OBSM_TASK_Q,O_RDWR);
	
		OS_CREATE_Q(MSG_HNDLR_Q);
		OS_GET_Q(MSG_HNDLR_Q,O_RDWR);
	}

//      create task handler thread
        if(0 != pthread_create(&gthreadIDs[gthreadIndex++], NULL,LanTask, NULL))
        {
        	printf("Error: file:%s,line:%d,create message thread error!\n"\
                	__FILE__, __LINE__);
        }
	
        //create message handler thread MsgHndlr
        if(0 != pthread_create(&gthreadIDs[gthreadIndex++], NULL,MsgHndlr, NULL))
        {
                printf("Error: file:%s,line:%d,create message thread error!\n"\
                        __FILE__, __LINE__);
        }
  */                                                              

/*
	//init mutex lock
	if(pthread_mutex_init(&sensorSdr_mutex,NULL) != 0)
	{
		printf("Error: Create sensorSdr_mutex error!\n");
	}
	if(pthread_mutex_init(&powerSta_mutex,NULL) != 0)
	{
		printf("Error: Create powerSta_mutex error!\n");
	}

*/
/*
	//create message handler thread
	if(0 != pthread_create(&gthreadIDs[gthreadIndex++], NULL, timer_task, NULL))
	{
		printf("Error: file:%s,line:%d,create timer thread error!\n"\
			__FILE__, __LINE__);
	}

	//create power manage thread
	#if(CONF_POWER_SUPPORT == 1)
	{
		if(0 != pthread_create(&gthreadIDs[gthreadIndex++], NULL, power_main, NULL))
		{
			printf("Error: file:%s,line:%d,create power thread error!\n",\
				__FILE__, __LINE__);
		}
	}
	#endif


	//create sensor manage thread
	#if(CONF_SENSOR_SUPPORT == 1)
	{
		if(0 != pthread_create(&gthreadIDs[gthreadIndex++], NULL, sensor_main, NULL))
		{
			printf("Error: file:%s,line:%d,create sensor thread error!\n",\
				__FILE__, __LINE__);
		}
	}
	#endif

	//create ipmb thread
	#if(CONF_IPMB_SUPPORT == 1)
	{
		if(0 != pthread_create(&gthreadIDs[gthreadIndex++], NULL, ipmb_main, NULL))
		{
			printf("Error: file:%s,line:%d,create ipmb thread error!\n"\
				__FILE__, __LINE__);
		}
	}
	#endif

	
*/	
//	udp_server(argc,&(*argv));

	/*for(i=0x4c;i<0x4f;i++)
	{
		if(0 == I2C_Master_Transmit(&i2c_dev,0x98, NULL, 0))
		{
			printf("---> Find device %#x\n",i);
		}

	}*/
/*	printf("------------ I2C2 ---------------\n");
	i2c_dev.bus = I2C2;
	//printf("---> i2c_dev.bus = %#x, I2C2=%#x\n",(uint32_t)i2c_dev.bus,(uint32_t)I2C2);
	for(i=0x4c;i<0x4f;i++)
	{
		if(0 == I2C_Master_Transmit(&i2c_dev,i<<1, NULL, 0))
		{
			printf("---> Find device %#x\n",i);
		}

	}
	printf("------------ I2C3 ---------------\n");
	i2c_dev.bus = I2C3;
	//printf("---> i2c_dev.bus = %#x, I2C3=%#x\n",(uint32_t)i2c_dev.bus,(uint32_t)I2C3);
	for(i=0x4c;i<0x4f;i++)
	{
		if(0 == I2C_Master_Transmit(&i2c_dev,i<<1, NULL, 0))
		{
			printf("---> Find device %#x\n",i);
		}

	}
*/	
//	printf("---> end test!\n");
/*	gpio_data_t gpin_data;
	while(1)
	{
		//printf("---> turn on!\n");
		gpin_data.port = GPIOD;
		gpin_data.pin = GPIO_PIN_12;
		gpin_data.data = 0;
		set_gpio_value(&gpin_data);
		sleep(1);
		//printf("---> turn off!\n");
		gpin_data.port = GPIOD;
		gpin_data.pin = GPIO_PIN_12;
		gpin_data.data = 1;
		set_gpio_value(&gpin_data);
		sleep(1);
	}*/

}




int InitBmcInfo(void)
{
	//init sensorInfo
	int i = 0;
	int j = 0;
	for(i=0;i<MAX_SENSOR_NUM;i++)	//init sdr
	{
		g_BMCInfo.sensorInfo[i].sensorSdr = getSensorSdr(i);	
	}
	for(i=0;i<MAX_SENSOR_NUM;i++)	//init sensor table
	{
		g_BMCInfo.sensorInfo[i].sensorDev = getSensorDev(i);	
	}
	for(i=0;i<MAX_SENSOR_NUM;i++)
	{
		g_BMCInfo.SDRConfig.RecordDataOffset[i]=0;
	}
	for(i=0;i<MAX_SENSOR_NUM;i++)
	{
		if(i<2)
			for(j=0;j<6;j++)	
				if(j<3)
					g_BMCInfo.SDRConfig.SDR[i][j] =0x80;	
				else
					g_BMCInfo.SDRConfig.SDR[i][j] =0x7f;
		else
			for(j=0;j<6;j++)
                                if(j<3)
                                        g_BMCInfo.SDRConfig.SDR[i][j] =0x00;
                                else
                                        g_BMCInfo.SDRConfig.SDR[i][j] =0xff;				
	}

}


int InitBMCSharedMem ()
{
        BMCInfo_t* pBMCInfo = &g_BMCInfo;
        pBMCInfo->MsgHndlrTblSize=7;
        memcpy(pBMCInfo->MsgHndlrTbl,m_MsgHndlrTbl,sizeof(m_MsgHndlrTbl));
        Set_BMCInfo_IPMIConfig_LANIfcSupport(1,1);
        Set_BMCInfo_IPMIConfig_SerialIfcSupport(1,1);
        BMCInfo_InitChConfig();
        return 0;
}

