/*
 *  Copyright 2007 by Texas Instruments Incorporated.
 *  All rights reserved. Property of Texas Instruments Incorporated.
 *  Restricted rights to use, duplicate or disclose this code are
 *  granted through contract.
 *
 *  @(#) TCP/IP_Network_Developers_Kit 1.93.00.09 08-16-2007 (ndk-c09)
 */
//--------------------------------------------------------------------------
// IP Stack Server Demonstration Program
//--------------------------------------------------------------------------
// newservers.c
//
// This module demonstrates the use of the server daemon added in NDK 1.7.
//
// It provides all the functionality of:
//     echosrv() : echosrv.c
//     datasrv() : datasrv.c
//     nullsrv() : nullsrv.c
//     oobsrv()  : oobsrv.c
//
// The original source files are still provided to illustrate a traditional
// server. This file contains only the daemon service task functions
// required when using the server daemon.
//
// Author: Michael A. Denio
// Copyright 2003 by Texas Instruments Inc.
//-------------------------------------------------------------------------
#include <csl_edma2.h>
#include <csl_intcAux.h>
#include "fa_server.h"
#include "common.h"
#include "environment.h"
#include "spb_processing.h"
#include "image_control.h"
#include "system_setup.h"
#include "capture_camera.h"
#include "SPBTest.h"
#include "data_indicator.h"
#include "spb_module_main.h"
#include "data_transfer.h"
#include "Ranger3DCam.h"
#include "capture.h"
#include "timer.h"
#include "nfa_camera.h"

/** 
 *   @file  echosrv.c
 *
 *   @brief   
 *      This program implements a TCP and UDP echo server, which echos back any
 *      input it receives.
 *
 *  \par
 *  NOTE:
 *      (C) Copyright 2008, Texas Instruments, Inc.
 *
 *  \par
 */

//configure TCP data buffer 

#define ECHO_BUFFER_MAX_SIZE		4 * 1024 * 1024
#pragma DATA_SECTION(EchoBuffer, ".sdram");
#pragma DATA_ALIGN(EchoBuffer, 1024);
unsigned char EchoBuffer[ECHO_BUFFER_MAX_SIZE];

#define GLOABL_TCP_BUFFER_SIZE	256 * 1024
#pragma DATA_SECTION(GlobalTCPRxDataBuffer, ".l2cache");
#pragma DATA_SECTION(GlobalTCPTxDataBuffer, ".l2cache");
#pragma DATA_ALIGN(GlobalTCPRxDataBuffer, 8);
#pragma DATA_ALIGN(GlobalTCPTxDataBuffer, 8);
unsigned char GlobalTCPRxDataBuffer[GLOABL_TCP_BUFFER_SIZE];
unsigned char GlobalTCPTxDataBuffer[GLOABL_TCP_BUFFER_SIZE];

unsigned char GlobalSysResultBuffer[1024];
unsigned char GlobalAppResultBuffer[1024];

#pragma DATA_SECTION(CPBDataBuffer, ".sdram");
#pragma DATA_ALIGN(CPBDataBuffer, 8);
unsigned char CPBDataBuffer[640*480*5];

#pragma DATA_ALIGN (ResponseDataAddr, 8)
unsigned int ResponseDataAddr[1];
//configure TCP socket
struct   sockaddr_in sin1;
SOCKET   stcp = INVALID_SOCKET;
SOCKET   sudp = INVALID_SOCKET;
SOCKET   sresult = INVALID_SOCKET;
SOCKET   stcpactive = INVALID_SOCKET;
SOCKET   stcpbusy;
fd_set ibits, obits, xbits;
int snd_count = 0;
int rcv_count = 0;
int      size,result;
HANDLE   hBuffer;
char     *pBuf;
char     *hBuf;
struct   timeval timeout;    
EDMA_Handle TCP_EdmaHandle;
int TCPEDMATCCNumber;
TTCPDataHeader TCPRXHeader, TCPTXHeader;
int remain_small_size;
int remain_large_size;
int remain_small_offset;
int remain_large_offset;
int test_Laser_MC_Status = 0;
int test_Laser_MC_Count = 0;
int test_Laser_Mc_Period = 0;
int test_Laser_Mc_Packet_Period = 0;
TCameraInitParam CameraInitData;

TCPControlInfo TcpPacketInfo;
TCPReceiveData TcpReceiveDataInfo;

TVirtualSPBProcessedData tempVirtualSPBProcessedData;

struct{
	unsigned int TabletNumber;
	int Result;
  	unsigned short CapturedTime[SYSTEM_SPB_CAMERA_COUNT];
	int currentTabletNum;
}SendData;

struct
{
	int Exist;
	int RemainingCount;
}RTImageData;

//20201106 cjg added 3d camera param
//20201020 cjg 3D camera param control
TCheckCamTimeOut CheckCamTimeOut;
T3DCameraVersion CamVerData;
TCamera3D_CalOffsetParam Camera3D_OffsetParamData;
TCamera3D_CalCOGParam Camera3D_COGParamData;

T3DCamera_ADC_Resolution Cam_ADC_ResolutionData;
TThreeDPositionInfo ThreeDPositionInfo_SPB;
void FA_TCPServer()
{
/*
	TCP_EdmaHandle = EDMA_open(EDMA_CHA_UXEVT, EDMA_OPEN_RESET);
	TCPEDMATCCNumber = EDMA_intAlloc(EDMA_CHA_UXEVT);
	EDMA_intClear(TCPEDMATCCNumber);
	EDMA_intDisable(TCPEDMATCCNumber);
	EDMA_disableChannel(TCP_EdmaHandle);
*/
	fdOpenSession( TaskSelf() );
	
	TcpPacketInfo.Status == SERVER_STATUS_IDLE;
	TcpPacketInfo.rx_control == SERVER_STATUS_RECEIVE;
	memset(&TcpPacketInfo, 0 ,sizeof(TCPControlInfo));
	memset(&TCPRXHeader, 0 ,sizeof(TTCPDataHeader));
	memset(&TCPTXHeader, 0 ,sizeof(TTCPDataHeader));

	// Create the main TCP listen socket
	sresult = FA_connect();	
	if(sresult == INVALID_SOCKET)
		FA_disconnect();

	// Configure our timeout to be 15 seconds
	timeout.tv_sec  = 0;
	timeout.tv_usec = 300000;

//	printf("EchoSrv Initialized\n");
	TcpPacketInfo.Status = SERVER_STATUS_RECEIVE;
	
	// Run until task is destroyed by the system
	for(;;)
	{
		FD_ZERO(&ibits);
		FD_ZERO(&obits);
		FD_ZERO(&xbits);

		FD_SET(stcp, &ibits);
		TcpPacketInfo.Status = SERVER_STATUS_RECEIVE;
//		FD_SET(sudp, &ibits);
//		CSL_intcGlobalDisable(&state);
//		event_state = CSL_intcEventDisable(CSL_INTC_EVENTID_MACRXINT);
		if(TcpPacketInfo.Status == SERVER_STATUS_RECEIVE || TcpPacketInfo.Status == SERVER_STATUS_IDLE)
		{
			ReceiveTCPPacket(pBuf);
		}
		
	    if(TcpPacketInfo.Status == SERVER_STATUS_PROCESSING)
		{
//			CSL_intcGlobalEnable(&state);
			Tcp_Processing(TcpPacketInfo);
//			CSL_intcGlobalDisable(&state);
		}
		if(TcpPacketInfo.Status == SERVER_STATUS_SEND)
		{
			SendTCPPacket(TcpPacketInfo);
		}

		TcpPacketInfo.Status = SERVER_STATUS_IDLE;
//		CSL_intcEventRestore(CSL_INTC_EVENTID_MACRXINT,event_state);
//		System_Sleep_ms(50);
//		SendData();
	}
}

SOCKET FA_connect()
{


    stcp = socket(AF_INET, SOCK_STREAMNC, IPPROTO_TCP);
    if( stcp == INVALID_SOCKET )
        return INVALID_SOCKET;

    // Set Port = 7, leaving IP address = Any
    bzero( &sin1, sizeof(struct sockaddr_in) );
    sin1.sin_family = AF_INET;
    sin1.sin_len    = sizeof( sin1 );
    sin1.sin_port   = htons(1002);

    // Bind socket
    if ( bind( stcp, (PSA) &sin1, sizeof(sin1) ) < 0 )
        return INVALID_SOCKET;

    // Start listening
    if ( listen( stcp, 1) < 0 )
        return INVALID_SOCKET;
	return stcp;
}


void FA_disconnect()
{
    if( stcp != INVALID_SOCKET )
	{	
        fdClose( stcp );
		stcp = INVALID_SOCKET;
	}
	TaskBlock( TaskSelf() );
}

void ReceiveTCPPacket(unsigned char *buf)
{
	unsigned int dataBufferMaxSize;
	
	if( stcp == INVALID_SOCKET ) 
		FA_disconnect();

    // Wait for socket activity
    if( stcpactive == INVALID_SOCKET )
    {
        // Wait without timeout
        result = fdSelect( 4, &ibits, &obits, &xbits, 0 );
    }
    else
    {
        // Wait for set timeout - abort active connection on no activity
        FD_SET(stcpactive, &ibits);
        result = fdSelect( 4, &ibits, &obits, &xbits, 0 );
        if( result <= 0 )
        {
//			printf("TimeOut Error!!! %x\n",stcpactive);
            fdClose( stcpactive );
            stcpactive = INVALID_SOCKET;
        }
    }

    if( result < 0 ){
	    FA_disconnect();
	}	
    // Check for a new TCP connection
    if( FD_ISSET(stcp, &ibits) )
    {
        // We have a new connection. Assign it so sbusy at
        // first...
		stcpactive = INVALID_SOCKET;
        size = sizeof( sin1 );
        stcpbusy = accept( stcp, (PSA)&sin1, &size );

        // If the active socket is free use it, else print out
        // a busy message
        if( stcpactive == INVALID_SOCKET )
	  {
            stcpactive = stcpbusy;
        }
        else
	 {
	       fdClose( stcpbusy );
	  }
    }

    // Check for new data on active TCP connection
    if( stcpactive != INVALID_SOCKET && FD_ISSET(stcpactive, &ibits) )
    {
        // There is data available on the active connection
        rcv_count = (int)recvnc( stcpactive, (void **)&buf, 0, &hBuffer );
//		printf("RECV data :%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7],buf[8],buf[9],buf[10],buf[11],buf[12],buf[13],buf[14],buf[15]);
		if (rcv_count <= 0 ){
                fdClose( stcpactive );
                stcpactive = INVALID_SOCKET;
		   return;
		}

		if(buf[0] == 0xa5 && buf[1] == 0xa5 && rcv_count == 16 && TcpPacketInfo.Command==0)
		{
			ReceiveTCPHeader(buf);
	
			TcpPacketInfo.Command = TCPRXHeader.Command;
			TcpPacketInfo.SmallDataAddress = (unsigned char *)GlobalTCPRxDataBuffer;
			TcpPacketInfo.LargeDataAddress = GetTCPBufferAddress(&dataBufferMaxSize);
			TcpPacketInfo.SmallDataSize = TCPRXHeader.SmallDataLength;
			TcpPacketInfo.LargeDataSize = TCPRXHeader.LargeDataLength;
			remain_small_size = TCPRXHeader.SmallDataLength;
			remain_large_size = TCPRXHeader.LargeDataLength;
			remain_small_offset = 0;
			remain_large_offset = 0;
			if(TCPRXHeader.SmallDataLength > 0  || TCPRXHeader.LargeDataLength > 0)
			{

				TcpPacketInfo.Status = SERVER_STATUS_RECEIVE;
				if(TCPRXHeader.LargeDataLength > 0 && TCPRXHeader.SmallDataLength <= 0)
				{
					TcpPacketInfo.rx_control= SERVER_CONTROL_RECEIVE_LARGE_DATA;
					TcpReceiveDataInfo.LargeDataSize= TCPRXHeader.LargeDataLength;
					TcpReceiveDataInfo.SmallDataSize= TCPRXHeader.SmallDataLength;
				}

				else if(TCPRXHeader.SmallDataLength > 0 && TCPRXHeader.LargeDataLength <= 0)
				{
					TcpPacketInfo.rx_control= SERVER_CONTROL_RECEIVE_SMALL_DATA;
					TcpReceiveDataInfo.LargeDataSize= TCPRXHeader.LargeDataLength;
					TcpReceiveDataInfo.SmallDataSize= TCPRXHeader.SmallDataLength;
				}
				else
				{
					TcpPacketInfo.rx_control= SERVER_CONTROL_RECEIVE_ALL_DATA;
					TcpReceiveDataInfo.LargeDataSize= TCPRXHeader.LargeDataLength;
					TcpReceiveDataInfo.SmallDataSize= TCPRXHeader.SmallDataLength;					
				}
				recvncfree( hBuffer );	
				return;
			}
			if(TCPRXHeader.RequestKind== CMD_TYPE_APP_RECEIVE_RESULT)
			{
				TcpPacketInfo.Status = SERVER_STATUS_PROCESSING;
				TcpPacketInfo.tx_control= SERVER_CONTROL_SEND_HEADER;
			}
			else
			{
				TcpPacketInfo.Status = SERVER_STATUS_SEND;
				TcpPacketInfo.tx_control= SERVER_CONTROL_SEND_HEADER;
			}

			recvncfree( hBuffer );	
			return ;	
		}
		if(TcpPacketInfo.rx_control == SERVER_CONTROL_RECEIVE_SMALL_DATA)
		{
		
			ReceiveSmallData(buf, rcv_count, remain_small_offset);
			remain_small_size -= rcv_count;
			remain_small_offset += rcv_count;
			if(remain_small_size > 0)
			{
				TcpPacketInfo.Status = SERVER_STATUS_RECEIVE;
				TcpPacketInfo.rx_control = SERVER_CONTROL_RECEIVE_SMALL_DATA;
				recvncfree( hBuffer );
				return; 
			}
			
			if(TCPRXHeader.RequestKind== CMD_TYPE_APP_RECEIVE_RESULT)
			{
				TcpPacketInfo.Status = SERVER_STATUS_PROCESSING;
			}
			else
			{
				TcpPacketInfo.Status = SERVER_STATUS_SEND;
			}

		}
		else if(TcpPacketInfo.rx_control == SERVER_CONTROL_RECEIVE_LARGE_DATA)
		{
			ReceiveLagreData(buf, rcv_count, remain_large_offset);
			remain_large_size -= rcv_count;
			remain_large_offset += rcv_count;
			if(remain_large_size > 0)
			{
				TcpPacketInfo.Status = SERVER_STATUS_RECEIVE;
				TcpPacketInfo.rx_control = SERVER_CONTROL_RECEIVE_LARGE_DATA;
				recvncfree( hBuffer );
				return; 
			}
			if(TCPRXHeader.RequestKind== CMD_TYPE_APP_RECEIVE_RESULT)
			{
				TcpPacketInfo.Status = SERVER_STATUS_PROCESSING;
			}
			else
			{
				TcpPacketInfo.Status = SERVER_STATUS_SEND;
			}

		}
		else if(TcpPacketInfo.rx_control == SERVER_CONTROL_RECEIVE_ALL_DATA){
			if(remain_small_size > 0)
			{
				ReceiveSmallData(buf, rcv_count, remain_small_offset);
				remain_small_size -= rcv_count;
				remain_small_offset += rcv_count;
				TcpPacketInfo.Status = SERVER_STATUS_RECEIVE;
				TcpPacketInfo.rx_control = SERVER_CONTROL_RECEIVE_ALL_DATA;
				recvncfree( hBuffer );
				return; 
			}
			if(remain_large_size > 0)
			{
				ReceiveLagreData(buf, rcv_count, remain_large_offset);
				remain_large_size -= rcv_count;
				remain_large_offset += rcv_count;
				if(remain_large_size <=0)
				{
					TcpPacketInfo.Status = SERVER_STATUS_SEND;
				}
				else
				{
					TcpPacketInfo.Status = SERVER_STATUS_RECEIVE;
					TcpPacketInfo.rx_control = SERVER_CONTROL_RECEIVE_ALL_DATA;
				}
				recvncfree( hBuffer );
				return;  
			}		
			if(TCPRXHeader.RequestKind== CMD_TYPE_APP_RECEIVE_RESULT)
			{
				TcpPacketInfo.Status = SERVER_STATUS_PROCESSING;
			}
			else
			{
				TcpPacketInfo.Status = SERVER_STATUS_SEND;
			}
		}
    	recvncfree( hBuffer );
    	TCP_TransferComplete();		
	}	
}

void SendTCPPacket(TCPControlInfo send)
{
	if(TCPRXHeader.Header == TCP_PACKET_HEADER)
		SendTCPHeader();
	if(TCPTXHeader.SmallDataLength > 0)
	{
		if(TCPRXHeader.RequestKind == CMD_TYPE_APP_REQUEST)
		{
			ResponseDataAddr[0] = 1;

			SendSmallData((unsigned char *)ResponseDataAddr,TCPTXHeader.SmallDataLength );
		}
		else if(TCPRXHeader.RequestKind == CMD_TYPE_APP_POLLING_RESULT)
		{
			ResponseDataAddr[0] = 1;
			SendSmallData((unsigned char *)ResponseDataAddr,TCPTXHeader.SmallDataLength );
		}
		else if(TCPRXHeader.RequestKind == CMD_TYPE_APP_RECEIVE_RESULT)
		{

			SendSmallData(TcpPacketInfo.ResultSmallDataAddress,TCPTXHeader.SmallDataLength);
		}
	}
	if(TCPTXHeader.LargeDataLength > 0)
	{
		SendSmallData(TcpPacketInfo.ResultLargeDataAddress,TCPTXHeader.LargeDataLength);
	}
	
	memset(&TCPRXHeader, 0 ,sizeof(TTCPDataHeader));
	memset(&TCPTXHeader, 0 ,sizeof(TTCPDataHeader));
	memset(&TcpPacketInfo, 0 ,sizeof(TCPControlInfo));
	TcpPacketInfo.Status = SERVER_STATUS_IDLE;
}

void ReceiveTCPHeader(unsigned char *buf)
{
/*
	EDMA_Config edmaConfig;
	unsigned int dataBufferMaxSize;
	edmaConfig.opt =  0x41300001 | ((TCPEDMATCCNumber & EDMA2_TCC_MASK) << EDMA2_TCC_SHIFT ) | ((TCPEDMATCCNumber & EDMA2_TCCM_MASK) << EDMA2_TCCM_SHIFT );  
	edmaConfig.cnt = rcv_count;	    			 
	edmaConfig.src = (Uint32) &buf[0];
	edmaConfig.dst = (Uint32) &TCPRXHeader;
	edmaConfig.idx = 0;

	EDMA_config(TCP_EdmaHandle, &edmaConfig);
	EDMA_setChannel (TCP_EdmaHandle);
	
	EDMA_intClear(TCPEDMATCCNumber);
    EDMA_intEnable(TCPEDMATCCNumber);
	EDMA_enableChannel(TCP_EdmaHandle);
*/
	memcpy(&TCPRXHeader,buf,rcv_count);
}

void ReceiveSmallData(unsigned char *buf, int size, int offset)
{
/*
	EDMA_Config edmaConfig;
	unsigned int dataBufferMaxSize;
	int tmp;
	edmaConfig.opt =  0x41300001 | ((TCPEDMATCCNumber & EDMA2_TCC_MASK) << EDMA2_TCC_SHIFT ) | ((TCPEDMATCCNumber & EDMA2_TCCM_MASK) << EDMA2_TCCM_SHIFT );  
	edmaConfig.cnt = size;	    			 
	edmaConfig.src = (Uint32) &buf[0];
	edmaConfig.dst = (Uint32) TcpPacketInfo.SmallDataAddress+offset;
	edmaConfig.idx = 0;

	EDMA_config(TCP_EdmaHandle, &edmaConfig);
	EDMA_setChannel (TCP_EdmaHandle);
	
//	EDMA_intClear(TCPEDMATCCNumber);
//    EDMA_intEnable(TCPEDMATCCNumber);
	EDMA_enableChannel(TCP_EdmaHandle);
//	printf("Receive SmallData size : %d\n",size);	
//	printf("Receive SmallData count : %d\n",++small_cnt);
//	TcpPacketInfo.rx_control = SERVER_CONTROL_RECEIVE_COMPLETE;
*/
	memcpy(TcpPacketInfo.SmallDataAddress+offset,buf,size);

}

void ReceiveLagreData(unsigned char *buf, int size, int offset)
{
/*
	EDMA_Config edmaConfig;
	unsigned int dataBufferMaxSize;
	edmaConfig.opt =  0x41300001 | ((TCPEDMATCCNumber & EDMA2_TCC_MASK) << EDMA2_TCC_SHIFT ) | ((TCPEDMATCCNumber & EDMA2_TCCM_MASK) << EDMA2_TCCM_SHIFT );  
	edmaConfig.cnt = size;	    			 
	edmaConfig.src = (Uint32) &buf[0];
	edmaConfig.dst = (Uint32) TcpPacketInfo.LargeDataAddress+offset;
	edmaConfig.idx = 0;

	EDMA_config(TCP_EdmaHandle, &edmaConfig);
	EDMA_setChannel (TCP_EdmaHandle);
	
	EDMA_intClear(TCPEDMATCCNumber);
    EDMA_intEnable(TCPEDMATCCNumber);
	EDMA_enableChannel(TCP_EdmaHandle);
//	printf("Receive LagreData size : %d\n",size);
*/
	//printf("Remain Large Data : %d\n", remain_large_size);

	//printf("Receive LagreData size : %d\n",size);
	memcpy(TcpPacketInfo.LargeDataAddress+offset,buf,size);

	TcpPacketInfo.rx_control = SERVER_CONTROL_RECEIVE_COMPLETE;
}

void SendTCPHeader()
{
	

	if(TCPRXHeader.RequestKind != CMD_TYPE_APP_RECEIVE_RESULT)
	{
		TCPTXHeader.Header 			= TCP_PACKET_HEADER;
		TCPTXHeader.Command	 		= TCPRXHeader.Command;
		TCPTXHeader.RequestKind 	= TCPRXHeader.RequestKind;
		TCPTXHeader.reserved		= 0x1234;
		TCPTXHeader.SmallDataLength	= sizeof(unsigned int);
		TCPTXHeader.LargeDataLength	= 0;
	}
	else
	{
		TCPTXHeader.Header 			= TCP_PACKET_HEADER;
		TCPTXHeader.Command	 		= TCPRXHeader.Command;
		TCPTXHeader.RequestKind 	= TCPRXHeader.RequestKind;
		TCPTXHeader.SmallDataLength	= (TcpPacketInfo.ResultSmallDataSize+ 3) / 4 * 4;
		TCPTXHeader.LargeDataLength	= (TcpPacketInfo.ResultLargeDataSize+ 3) / 4 * 4;
	}
		
//	mmCopy( hBuf, &TCPTXHeader, cnt );

	snd_count = send( stcpactive, &TCPTXHeader, sizeof(TTCPDataHeader), 0 );
//	printf("SEND data :%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",hBuf[0],hBuf[1],hBuf[2],hBuf[3],hBuf[4],hBuf[5],hBuf[6],hBuf[7],hBuf[8],hBuf[9],hBuf[10],hBuf[11],hBuf[12],hBuf[13],hBuf[14],hBuf[15]);
//	printf("Send Header size : %d\n",snd_count);
	if( snd_count < 0 )
    {
        fdClose( stcpactive );
        stcpactive = INVALID_SOCKET;
    }
}

void SendSmallData(unsigned char *buf, int size)
{
	snd_count = send( stcpactive, buf, size, 0 );
	if( snd_count < 0 )
    {
        fdClose( stcpactive );
        stcpactive = INVALID_SOCKET;
    }
//	printf("Send SmallData size : %d\n",snd_count);
//	printf("Send SmallData data : %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",*buf, *buf+1,*buf+2,*buf+3,*buf+4,*buf+5,*buf+6,*buf+7,*buf+8,*buf+9,*buf+10,*buf+11,*buf+12,*buf+13,*buf+14,*buf+15);
	TcpPacketInfo.tx_control == SERVER_CONTROL_SEND_COMPLETE;	
}

void SendLagreData(unsigned char *buf, int size)
{
	snd_count = send( stcpactive, buf, size, 0 );
	if( snd_count < 0 )
    {
        fdClose( stcpactive );
        stcpactive = INVALID_SOCKET;
    }
//	printf("Send LagreData size : %d\n",snd_count);
	TcpPacketInfo.tx_control == SERVER_CONTROL_SEND_COMPLETE;

}

void TCP_TransferComplete(void)
{

}

unsigned char *GetTCPBufferAddress(unsigned int *bufferMaxSize)
{
	unsigned short command = TCPRXHeader.Command;
	if (command == CMD_ECHO)
	{
		*bufferMaxSize = ECHO_BUFFER_MAX_SIZE;
		return (unsigned char *)EchoBuffer;		
	}
	else if (command == CMD_DOWNLOAD)
	{
		*bufferMaxSize = DOWNLOAD_MAX_SIZE;
		return (unsigned char *)ProgramBuffer;		
	}
	else if (command == CMD_SETUP_DATA)
	{
		*bufferMaxSize = sizeof(TTabletSetupData);
		return (unsigned char *) &TabletSetupData_SPB;
	}
	else if (command == CMD_SETUP_DATA_3D)
	{
		*bufferMaxSize = sizeof(TTablet3DSetupData);
		return (unsigned char *) &Tablet3DSetupData_SPB;
	}
	else if (command == CMD_STUDY_DATA)
	{
		*bufferMaxSize = sizeof(TTabletStudyResultData);
		return (unsigned char *) &TabletStudyResultData_SPB;
	}
	else if (command == CMD_VIRTUAL_INSPECTION_SET_IMAGE)
	{
		*bufferMaxSize = sizeof(DummyImage[0]);
		return (unsigned char *) &DummyImage[3];
	}
	else
	{
		*bufferMaxSize = 0;
		return NULL;
	}
}

void Tcp_Processing()		// called from main loop
{
	unsigned int *returnData;
	//unsigned int t1,t2;
	unsigned int VerChkl,VerChk2; //sjm Add
	TCaptureCommandParam *captureCommandParam;
	unsigned short command = TcpPacketInfo.Command;
	TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)GlobalTCPTxDataBuffer;
	TcpPacketInfo.ResultSmallDataSize = 0;
	TcpPacketInfo.ResultLargeDataAddress = NULL;
	TcpPacketInfo.ResultLargeDataSize = 0;
	TcpPacketInfo.LargeDataSize = TcpReceiveDataInfo.LargeDataSize;
	TcpPacketInfo.SmallDataSize = TcpReceiveDataInfo.SmallDataSize;

	memset(&TcpReceiveDataInfo, 0 , sizeof(TCPReceiveData));

#ifdef FPGA220
	/* sjm Add */
//	MMIO_VERSION_FPGA_V5L	= 0xFA;  //sjm Add
//	MMIO_VERSION_FPGA_V5H	= 0xFA;  //sjm Add
//	FPGAnewVersion2.VersionL = MMIO_VERSION_INFO_L;
//	FPGAnewVersion2.VersionH = MMIO_VERSION_INFO_H;
//	VerChk2 =(MMIO_VERSION_INFO_L & 0xf0) >> 4;
//	VerChkl =(MMIO_VERSION_INFO_H & 0x0f);
	//  Release 시 풀어야 함.
//	if((VerChkl == 2) & (VerChk2 == 2))
//	{
		//ErrorUnit_Put(BoardID, ERROR_TYPE_MESSAGE, ERROR_CODE_CPB_PROCESS_TIMEOUT, VerChkl, VerChk2,555);
//		;
//	}else
//	{
		//ErrorUnit_Put(BoardID, ERROR_TYPE_MESSAGE, ERROR_CODE_CPB_PROCESS_TIMEOUT, VerChkl, VerChk2,444);
//		return;
//	}
#endif


	if (command == CMD_READ_ERROR_LIST)
	{
		int maxCount;
		int getCount;
		maxCount = *(int *) TcpPacketInfo.SmallDataAddress;
		if (maxCount > 16) maxCount = 16;
		getCount = ErrorQueue_Get(GlobalSysResultBuffer + sizeof(int), maxCount);
		ErrorQueue_Remove(getCount);
		/*
		if (CheckFirstComm)
		{
			CPBBootEnable = 1;
			CheckFirstComm = 0;
		}
		*/
		*(int *)GlobalSysResultBuffer = getCount;
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)GlobalSysResultBuffer;
		TcpPacketInfo.ResultSmallDataSize = getCount * sizeof(TErrorUnit) + sizeof(int);
	}
	else if (command == CMD_TABLET_PROCESS_INFO)
	{
		int requestNum;
		requestNum = *(int *) TcpPacketInfo.SmallDataAddress;

		if (requestNum == 1)
		{
			TcpPacketInfo.ResultLargeDataAddress = (unsigned char *)&SPBTabletProcessInfo;
			TcpPacketInfo.ResultLargeDataSize = sizeof(TSPBTabletProcessInfo);
		}
		else if (requestNum == 2)
		{
			TcpPacketInfo.ResultLargeDataAddress = (unsigned char *)MakeInformationData();
			TcpPacketInfo.ResultLargeDataSize = sizeof(TProcessingImageBufferData);
		}
	}
	else if (command == CMD_GET_SPB_PRINT_RESULT)
	{
		int requestNum;
		
		TcpPacketInfo.ResultLargeDataAddress = (unsigned char *)PrintMatchingResult_SPB;
		TcpPacketInfo.ResultLargeDataSize = sizeof(unsigned int) * 512 * 3;
	}
	else if (command == CMD_CAPTURE_EXIST)
	{		
		unsigned int camNo;
		camNo = *(unsigned int *) TcpPacketInfo.SmallDataAddress;
		returnData = (unsigned int *)GlobalSysResultBuffer;
		//returnData[0] = ImageControl_GetCapturedFrameCount(camNo);
		returnData[0] = ImageControl_CalibMode_GetCapturedFrameCount(camNo);
		returnData[1] = ImageControl_CalibMode_GetMaxFrameCount(camNo);
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)GlobalSysResultBuffer;
		TcpPacketInfo.ResultSmallDataSize = 2 * sizeof(unsigned int);
	}
	else if (command == CMD_READ_SYSTEM_SETUP)
	{		
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *) &SystemSetupData;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TSPBSystemSetupData);
	}
	else if (command == CMD_DOWNLOAD)
	{
		CSL_IntcGlobalEnableState 	state;
		unsigned int pID, result;
		int time;
		CSL_intcGlobalDisable(&state);
		pID = *(unsigned int *)TcpPacketInfo.SmallDataAddress;
		time = *((int *)TcpPacketInfo.SmallDataAddress + 1);
		
		if(pID == PID_ENVIRONMENT)
		{
			ModifySystemSetup((TSPBSystemSetupData *) TcpPacketInfo.LargeDataAddress);
		}
		else
		{
			result = WriteToFlash(pID, TcpPacketInfo.LargeDataAddress, TcpPacketInfo.LargeDataSize, time);
		}
		CSL_intcGlobalEnable(&state);
	}
	else if (command == CMD_RESET)
	{
		System_Reset_Trigger_Time = Board1MSTmr;
		System_Reset_SW = TRUE;		
	}
	else if (command == CMD_GET_MAX_LASER_PROCESSING_TIME)
	{
		Max_Laser_Position_Processing_Time = *(int *) (TcpPacketInfo.SmallDataAddress + 0);
	}
	else if (command == CMD_SEND_LASER_CAL_DATA)
	{
		LaserCalInPutDataX = *(int *) (TcpPacketInfo.SmallDataAddress + 0);
 		LaserCalInPutDataY = *(int *) (TcpPacketInfo.SmallDataAddress + 4);
	}
	else if (command == CMD_CAPTURE_SETUP)
	{
		TCaptureSetupData *captureSetupData;
		captureSetupData = (TCaptureSetupData *) TcpPacketInfo.SmallDataAddress;
		
//		Calib_Capture_Stop_All();
		if (captureSetupData->CaptureType == CAPTURE_TYPE_SINGLE_CAPTURE)
		{
			TabletCapture_CaptureMode(captureSetupData->CaptureMode, captureSetupData->FrameBufferCount,
				captureSetupData->CameraMask, captureSetupData->ShutterSpeed, captureSetupData->ShutterDelay,
				captureSetupData->TriggerFreq,captureSetupData->SubsamplingMode, 1, captureSetupData->TabletType,captureSetupData->SensorLength);
		}
		else if (captureSetupData->CaptureType == CAPTURE_TYPE_FULL_CAPTURE)
		{
			TabletCapture_CaptureMode(captureSetupData->CaptureMode, captureSetupData->FrameBufferCount,
				captureSetupData->CameraMask, captureSetupData->ShutterSpeed, captureSetupData->ShutterDelay,
				captureSetupData->TriggerFreq,captureSetupData->SubsamplingMode, 0, captureSetupData->TabletType,captureSetupData->SensorLength);
		}
	}
	else if (command == CMD_STUDY_RESULT)
	{
		int camIndex;
		camIndex = *(int *) TcpPacketInfo.SmallDataAddress;

		TcpPacketInfo.ResultLargeDataAddress = (unsigned char *) &StudyResultData_SPB[camIndex];
		TcpPacketInfo.ResultLargeDataSize = sizeof(TStudyResultData_SPB);
		//TcpPacketInfo.ResultSmallDataAddress = (unsigned char *) &StudyResultData_SPB[camIndex];
		//TcpPacketInfo.ResultSmallDataSize = sizeof(TStudyResultData_SPB);
	}
	else if (command == CMD_STUDY_READY)
	{
		memcpy(&StudySetupData_SPB, TcpPacketInfo.SmallDataAddress, sizeof(TStudySetupData));
		Calib_Capture_Stop_All();
		SPB_Study_Ready();
		TabletCapture_StudyMode();
	}
	else if (command == CMD_STUDY_END)
	{
		SPB_Study_Stop();
		TabletCapture_Stop();
		Calib_Capture_Stop_All();
	}
	else if (command == CMD_SETUP_START)
	{
		int mode;
		mode = *(int *) TcpPacketInfo.SmallDataAddress;
		if (mode == SPB_SETUP_MODE_STUDY)
		{
			SPB_Study_Setup_Start();
		}
		else if (mode == SPB_SETUP_MODE_INSPECTION)
		{
			SPB_Inspection_Setup_Start();
		}
		else
		{
			SPB_Grade_Change_Start();
		}
	}
	else if (command == CMD_SPB_SETUP_STATUS)
	{
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *) &SPBProcessingSetupInfo;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TSPBProcessingSetupInfo);
	}
	else if (command == CMD_INSPECTION_READY)
	{
		memcpy(&InspectData_SPB, TcpPacketInfo.SmallDataAddress, sizeof(TInspectData));		
		Calib_Capture_Stop_All();
		SPB_Inspection_Ready(InspectData_SPB.MaxProcessingWaitingTime);
		TabletCapture_InspectionMode();
	}
	else if (command == CMD_INSPECTION_CLEAR)
	{
		SPB_Inspection_Clear();
		Calib_Capture_Stop_All();
	}
	else if (command == CMD_INSPECTION_END)
	{
		SPB_Inspection_Stop();
		TabletCapture_Stop();
		Calib_Capture_Stop_All();
	}
	else if (command == CMD_RUN_INFO)
	{
		CPBRunStatus.Running = RunInfo.RunSW;
		CPBRunStatus.CurrentCPBIndex = RunInfo.CurrentCPBIndex;
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *) &CPBRunStatus;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TCPBRunStatus);

		if(VirtualInspectionSW)
		{
			VirtualTabletNumberSensor1 = 0;
			VirtualTabletNumberSensor2 = 0;
			VirtualInspectionCount = 0;
			VirtualProcessedDataCount = 0;
			memset(VirtualCPBProcessedData, 0, sizeof(TVirtualCPBProcessedData) * 800);
			memset(VirtualSPBProcessedData, 0, sizeof(TVirtualSPBProcessedData) * (SPB_TABLET_LIST_COUNT + 1));
			memset(VirtualCPBProcessingIndex, 0, sizeof(int) * SYSTEM_CPB_COUNT);			
			memset(VirtualCPBStatus, 0, sizeof(TVirtualCPBStatus ) * SYSTEM_CPB_COUNT);
			VirtualDataRenewalSW = 0;
			VirtualInspectionSW = 0;
		}
	}
	else if (command == CMD_TABLET_CHARACTER)
	{
		memcpy(&TabletCharacter_SPB, TcpPacketInfo.SmallDataAddress, sizeof(TTabletCharacter));
	}
/*
	else if (command == CMD_STUDY_DATA)
	{
		memcpy(&TabletStudyData_SPB, smallData, sizeof(TTabletStudyData));
	}
*/
	else if (command == CMD_GRADE_DATA)
	{
		memcpy(&TabletGradeData_SPB, TcpPacketInfo.SmallDataAddress, sizeof(TTabletGradeData));
	}
	else if (command == CMD_TABLET_CAPTURE_SETUP_DATA)
	{
		unsigned char *imageBuffer; 
		int spbCamIndex;
		for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
		{
			if (SystemSetupData.CamMask & (0x01 << spbCamIndex))
			{
				if(spbCamIndex == 0)
					imageBuffer = ImageBuffer1;
				else if(spbCamIndex == 1)
					imageBuffer = ImageBuffer2;
				else if(spbCamIndex == 2)
					imageBuffer = ImageBuffer3;
				else if(spbCamIndex == 3)
					imageBuffer = ImageBuffer4;		

				SelectedImageControl_ClearBuffer(imageBuffer);
			}
		}

		RealtimeImageStartQueue = RealtimeImageEndQueue = 0;
		ImageControlInterval = 1;

		memcpy(&TabletCaptureSetupData, TcpPacketInfo.SmallDataAddress, sizeof(TTabletCaptureSetupData));
	}
	else if (command == CMD_SET_CAMERA_WHITE_BALANCE)
	{
		memcpy(WhiteBalanceInfo_SPB, TcpPacketInfo.SmallDataAddress, sizeof(TWhiteBalanceInfo) * SYSTEM_TOTAL_CAMERA_COUNT);
	}
	else if (command == CMD_DEFECT_IMAGE_EXIST)
	{
		int minDefectTabletNumber;
		minDefectTabletNumber = *(int *)TcpPacketInfo.SmallDataAddress;
		SearchDefectImage(minDefectTabletNumber, (TDefectImageInfo *)GlobalSysResultBuffer);
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)GlobalSysResultBuffer;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TDefectImageInfo);
	}
	else if (command == CMD_DEFECT_IMAGE)
	{
		int bufferIndex;
		bufferIndex = *(int *)TcpPacketInfo.SmallDataAddress;
		TcpPacketInfo.ResultLargeDataAddress = (unsigned char *)GetDefectImageAddr(bufferIndex);
		if(TabletCharacter_SPB.HighResolutionImage && SystemSetupData.CameraKind[bufferIndex] == CAMERA_KIND_NFA_2D)
		{
			TcpPacketInfo.ResultLargeDataSize = HD_IMAGE_WIDTH * HD_IMAGE_HEIGHT;
		}
		else
		{
			TcpPacketInfo.ResultLargeDataSize = CAPTURE_WIDTH * CAPTURE_HEIGHT;
		}
	}
	else if (command == CMD_CHECK_RT_IMAGE_EXIST)
	{
		if(RealtimeImageStartQueue != RealtimeImageEndQueue)
		{
			RTImageData.Exist = 1;
			if(RealtimeImageStartQueue < RealtimeImageEndQueue)
			{
				RTImageData.RemainingCount = RealtimeImageEndQueue - RealtimeImageStartQueue;
			}
			else
			{
				RTImageData.RemainingCount = RealtimeImageEndQueue + (MAX_REALTIME_BUFFER_SIZE - RealtimeImageStartQueue);
			}
		}
		else
		{
			RTImageData.Exist = 0;
			RTImageData.RemainingCount = 0;
		}
									
		TcpPacketInfo.ResultLargeDataAddress = (unsigned char *) &RTImageData;
		TcpPacketInfo.ResultLargeDataSize = sizeof(RTImageData);	
	}
	else if (command == CMD_GET_REALTIME_IMAGE)
	{						
		TcpPacketInfo.ResultLargeDataAddress = (unsigned char *) RealtimeImageBuffer + REALTIME_IMAGE_SIZE * RealtimeImageStartQueue;
		TcpPacketInfo.ResultLargeDataSize = REALTIME_IMAGE_SIZE;

		RealtimeImageStartQueue = RealtimeImageStartQueue + 1;
		if(RealtimeImageStartQueue >= MAX_REALTIME_BUFFER_SIZE) RealtimeImageStartQueue = 0;
	}
	else if (command == CMD_DEFECT_DATA)
	{
		int bufferIndex;
		bufferIndex = *(int *)TcpPacketInfo.SmallDataAddress;
		TcpPacketInfo.ResultLargeDataAddress = (unsigned char *)GetDefectDataAddr(bufferIndex);
		TcpPacketInfo.ResultLargeDataSize = sizeof(TDefectData_SPB);
	}
	else if (command == CMD_DISCARD_DEFECT_IMAGE)
	{
		DiscardDefectImage();
	}
	else if (command == CMD_RUN)
	{
		TFFID pID;
		unsigned int runMode, runMaskL, runMaskH;
		runMode = *((unsigned int *)TcpPacketInfo.SmallDataAddress);
		pID = *((TFFID *)TcpPacketInfo.SmallDataAddress + 1);
		runMaskL = *((unsigned int *)TcpPacketInfo.SmallDataAddress + 2);
		runMaskH = *((unsigned int *)TcpPacketInfo.SmallDataAddress + 3);
		CPB_Run_Ready(runMode, runMaskL, runMaskH, pID);
	}
	else if (command == CMD_CAMERA_CONTROL_NORMAL_MODE ||
				command == CMD_CAMERA_CONTROL_PROCESSING_MODE)
	{		
		// 2018-05-04 moon test
		char *retAddr;

		unsigned int RXDataLength, TXDataLength;
		int camera_num;
		char test_temp[2]={'0','0'}; 
		int CMD_ST_PTR = 4;
		char lowerCmd;
		char higherCmd;

		TXDataLength = *(TcpPacketInfo.SmallDataAddress);
		RXDataLength = *(TcpPacketInfo.SmallDataAddress + 1);
		camera_num = *(TcpPacketInfo.SmallDataAddress + 5);
		camera_num = (camera_num >> 4) - 1;
			
		while(ExpectedRS232ReceiveDataCount);
			
		retAddr = (char *)NFACameraControl(TXDataLength, RXDataLength, TcpPacketInfo.SmallDataAddress + 2, 0);
		
		if(!(retAddr[0] == 'T' && retAddr[0] == 'O'))
		{
			lowerCmd = *(TcpPacketInfo.SmallDataAddress + CMD_ST_PTR + 2);
			higherCmd = *(TcpPacketInfo.SmallDataAddress + CMD_ST_PTR + 3);
			if(lowerCmd == CAMERA_DATA_CMD_SHUTTER_L && higherCmd == CAMERA_DATA_CMD_SHUTTER_H)
			{
				if(SystemSetupData.CameraKind[camera_num] != CAMERA_KIND_NFA_3D)
				{
					NFACaptureInfo[camera_num].CaptureKind = CAPTURE_KIND_FRAME;
					NFACaptureInfo[camera_num].DMATriggerCount = 0;
					NFACamEdmaParamSet[camera_num].dstAddr = (Uint32) InvalidImage;
					NFA_CAMERA_CONTROL_HARDWARE_TRIG = (0x01 << camera_num);
					Sleep(50); // 트리거에 대한 처리가 완료될때까지 대기한다 (대기하지 않는 경우 이미지 어드레스가 꼬이는 경우가 발생)
				}				
			}		
		}

		TcpPacketInfo.ResultSmallDataAddress = (char *)retAddr;
		TcpPacketInfo.ResultSmallDataSize = RXDataLength;		
	}
	else if (command == CMD_CAMERA_CONTROL_PARTIAL_MODE)
	{		
		// 2018-05-04 moon test
		char *retAddr;

		unsigned int RXDataLength, TXDataLength;
		int camera_num;
		char test_temp[2]={'0','0'}; 
		int CMD_ST_PTR = 4;
		char lowerCmd;
		char higherCmd;

		TXDataLength = *(TcpPacketInfo.SmallDataAddress);
		RXDataLength = *(TcpPacketInfo.SmallDataAddress + 1);
		camera_num = *(TcpPacketInfo.SmallDataAddress + 5);
		camera_num = (camera_num >> 4) - 1;

		while(ExpectedRS232ReceiveDataCount);
			
		retAddr = (char *)NFACameraControl(TXDataLength, RXDataLength, TcpPacketInfo.SmallDataAddress + 2, 1);
		
		if(!(retAddr[0] == 'T' && retAddr[0] == 'O'))
		{
			lowerCmd = *(TcpPacketInfo.SmallDataAddress + CMD_ST_PTR + 2);
			higherCmd = *(TcpPacketInfo.SmallDataAddress + CMD_ST_PTR + 3);
    
			if(lowerCmd == CAMERA_DATA_CMD_SHUTTER_L && higherCmd == CAMERA_DATA_CMD_SHUTTER_H)
			{
				if(SystemSetupData.CameraKind[camera_num] != CAMERA_KIND_NFA_3D)
				{
					NFACaptureInfo[camera_num].CaptureKind = CAPTURE_KIND_FRAME;
					NFACaptureInfo[camera_num].DMATriggerCount = 0;
					NFACamEdmaParamSet[camera_num].dstAddr = (Uint32) InvalidImage;

					NFA_CAMERA_CONTROL_HARDWARE_TRIG = (0x01 << camera_num);

					Sleep(50); // 트리거에 대한 처리가 완료될때까지 대기한다 (대기하지 않는 경우 이미지 어드레스가 꼬이는 경우가 발생)
				}				
			}		
		}

		TcpPacketInfo.ResultSmallDataAddress = (char *)retAddr;
		TcpPacketInfo.ResultSmallDataSize = RXDataLength;		
	}
	else if (command == CMD_INT_CAPTURE)
	{
		int value;
		value = *((int *)TcpPacketInfo.SmallDataAddress);
		if (value == 0)
		{
			ClearIntCapture();
		}
		else if (value == 1)
		{
			ResetIntCapture();
		}
	}
	else if (command == CMD_CIS_PARTIAL_CAPTURE_MODE)
	{
		unsigned char *imageBuffer; 
		int spbCamIndex;
		for (spbCamIndex = 0; spbCamIndex < SYSTEM_SPB_CAMERA_MAX_COUNT; spbCamIndex++)
		{
			if (SystemSetupData.CamMask & (0x01 << spbCamIndex))
			{
				if(spbCamIndex == 0)
					imageBuffer = ImageBuffer1;
				else if(spbCamIndex == 1)
					imageBuffer = ImageBuffer2;
				else if(spbCamIndex == 2)
					imageBuffer = ImageBuffer3;
				else if(spbCamIndex == 3)
					imageBuffer = ImageBuffer4;		

				SelectedImageControl_ClearBuffer(imageBuffer);
			}
		}
	}
	else if (command == CMD_CAPTURE_START)
	{
		captureCommandParam = (TCaptureCommandParam *)TcpPacketInfo.SmallDataAddress;

		Calib_Capture_Start(captureCommandParam->CaptureKind, captureCommandParam->CameraMask, captureCommandParam->CaptureMode, 
			captureCommandParam->FrameBufferCount, captureCommandParam->ShutterSpeed, captureCommandParam->SubsamplingMode);

		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)GlobalSysResultBuffer;
		TcpPacketInfo.ResultSmallDataSize = 0;
	}
	else if (command == CMD_CAPTURE_STOP)
	{
		unsigned int spbCameraIndex;
		spbCameraIndex = *(unsigned int *) TcpPacketInfo.SmallDataAddress;
		Calib_Capture_Stop(spbCameraIndex);
		TabletCapture_Stop();
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)GlobalSysResultBuffer;
		TcpPacketInfo.ResultSmallDataSize = 0;
	}
	else if (command == CMD_VIRTUAL_INSPECTION_CHECK_IMAGE)
	{
		unsigned int camNo;
		unsigned int bufferReadSize;
		camNo = *(unsigned int *) TcpPacketInfo.SmallDataAddress;
		bufferReadSize = *(unsigned int *) (TcpPacketInfo.SmallDataAddress + 4);

		TcpPacketInfo.ResultLargeDataAddress = (unsigned char *) DummyImage[camNo];
		TcpPacketInfo.ResultLargeDataSize = bufferReadSize;//SYSTEM_CAMERA_HD_WIDTH * SYSTEM_CAMERA_HD_HEIGHT;
	}	
	else if (command == CMD_CAPTURE_UPLOAD)
	{
		unsigned int camNo;
		unsigned int bufferReadSize;
		camNo = *(unsigned int *) TcpPacketInfo.SmallDataAddress;
		bufferReadSize = *(unsigned int *) (TcpPacketInfo.SmallDataAddress + 4);
		TcpPacketInfo.ResultLargeDataAddress = (unsigned char *) ImageControl_CalibMode_GetFirstValidFrameBuffer(camNo);
		TcpPacketInfo.ResultLargeDataSize = bufferReadSize;
		ImageControl_CalibMode_DecreaseToNextValidFrame(camNo);
	}	
	else if (command == CMD_IDLE_PROCESS_INFO)
	{
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *) &IdleProcessData;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TIdleProcessData);
	}
	else if (command == CMD_3D_CAMERA_DATA)
	{
		// 사용하지 않는 command, 3D 카메라 테스트로 임시 사용

		unsigned int camNo;
		unsigned int bufferReadSize;
		camNo = *(unsigned int *) TcpPacketInfo.SmallDataAddress;
		bufferReadSize = *(unsigned int *) (TcpPacketInfo.SmallDataAddress + 4);
		TcpPacketInfo.ResultLargeDataAddress = (unsigned char *) ImageBuffer2;
		TcpPacketInfo.ResultLargeDataSize = bufferReadSize;
	}
	else if (command == CMD_CAMERA_SETUP)
	{
		// 사용하지 않는 command, 3D 카메라 테스트로 임시 사용

		unsigned int trig = *(unsigned int *) TcpPacketInfo.SmallDataAddress;

		Set_3D_LineScanTime(trig,1);
		CHANGE_2D3D_REG = (0x01 << 1);
		ThreeDBufferCheckSW = 1;
	}
	else if (command == CMD_NFA_2D_CAM_PARTIAL_AREA)
	{
		NFA2DCameraAreaInfo.topPosition = *(unsigned int *) (TcpPacketInfo.SmallDataAddress);
		NFA2DCameraAreaInfo.bottomPosition = *(unsigned int *) (TcpPacketInfo.SmallDataAddress + 4);
	}
	else if (command == CMD_CAMERA_CONFIG)
	{
		// 3d 카메라 Calibration이 완료되면 Frame 모드를 사용할 일이 없다.
		// UI에서 Calibration 종료시에 자동으로 해당 변수를 0으로 세팅한다.
		global3DCameraFrameCaptureSW = 0;		
	}
	else if (command == CMD_PROCESSING_TIME)
	{
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *) ProcessingTimeList;
		TcpPacketInfo.ResultSmallDataSize = SPB_TABLET_LIST_COUNT * sizeof(TProcessingTime);		
	}
	else if (command == CMD_CPB_STATUS)
	{
		int cpbIndex; 
		for (cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
		{
			// -1 : disabled, 0 : idle, 1 : busy
			CPBStatus[cpbIndex].reserved = CPBStep[cpbIndex] + 1;
		}

		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *) CPBStatus;
		TcpPacketInfo.ResultSmallDataSize = SYSTEM_CPB_COUNT * sizeof(TCPBStatus);		
	}
	else if (command == CMD_FLASH_INFO)
	{
		TcpPacketInfo.ResultLargeDataAddress = (unsigned char *) GetFileSystem();
		TcpPacketInfo.ResultLargeDataSize = sizeof(TFFSystem);
//		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *) GetFileSystem();
//		TcpPacketInfo.ResultSmallDataSize = sizeof(TFFSystem);

//		*resultLargeDataAddress = (unsigned char *) GetFileSystem();
//		*resultLargeDataSize = sizeof(TFFSystem);
	}
	else if (command == CMD_FLASH_FORMAT)
	{
		FlashFormat();
	}
	else if (command == CMD_READ_PROGRAM_HEADER)
	{
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&SPBProgramHeader;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TSPBProgramHeader);
	}
	else if (command == CMD_READ_DB_HEADER)
	{
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&SPBDBHeader;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TSPBDBHeader);
	}
	else if (command == CMD_STOP_SPB_TEST)
	{
		SPBTestStop();
	}
	else if (command == CMD_USB_TEST)
	{
		unsigned int func;
		func = *((unsigned int *) TcpPacketInfo.SmallDataAddress);
		if (func == 1)
		{
//			USB_DISC_Test();
		}
	}
	else if (command == CMD_HPI_TEST)
	{
		int testKind;
		testKind = *((int *) TcpPacketInfo.SmallDataAddress);
		HPITestStart(testKind);
	}	
	else if (command == CMD_VIRTUAL_INSPECTION_START)
	{
		int m;

		memcpy(&CPBVirtualInspectionData, TcpPacketInfo.SmallDataAddress, sizeof(TCPBVirtualInspectionData));

		for(m = 0; m < SYSTEM_SPB_CAMERA_COUNT; m++)
		{
			if(CPBVirtualInspectionData.CameraMask & (0x01 << m))
				CameraSetupData.CameraEnable[m] = 1;
			else
				CameraSetupData.CameraEnable[m] = 0;
		}		
		VirtualTriggerTime = Board1MSTmr;
		VirtualTabletNumberSensor1 = 0;
		VirtualTabletNumberSensor2 = 0;
		VirtualInspectionCount = 0;
		VirtualProcessedDataCount = 0;
		memset(VirtualCPBProcessedData, 0, sizeof(TVirtualCPBProcessedData) * 800);
		memset(VirtualSPBProcessedData, 0, sizeof(TVirtualSPBProcessedData) * (SPB_TABLET_LIST_COUNT + 1));
		memset(VirtualCPBProcessingIndex, 0, sizeof(int) * SYSTEM_CPB_COUNT);			
		memset(VirtualCPBStatus, 0, sizeof(TVirtualCPBStatus ) * SYSTEM_CPB_COUNT);
		VirtualDataRenewalSW = 0;
		VirtualInspectionSW = 1;			
		
		SPB_Study_Ready();		
	}
	else if (command == CMD_VIRTUAL_INSPECTION_END)
	{
		int buf;
		buf = *(int *) TcpPacketInfo.SmallDataAddress;

		if(buf == 0)
			VirtualInspectionSW = 0;
		else
		{
			VirtualTabletNumberSensor1 = 0;
			VirtualTabletNumberSensor2 = 0;

			VirtualInspectionCount = 0;
			VirtualProcessedDataCount = 0;
			memset(VirtualCPBProcessedData, 0, sizeof(TVirtualCPBProcessedData) * 800);
			memset(VirtualSPBProcessedData, 0, sizeof(TVirtualSPBProcessedData) * (SPB_TABLET_LIST_COUNT + 1)) ;
			memset(VirtualCPBStatus, 0, sizeof(TVirtualCPBStatus ) * SYSTEM_CPB_COUNT);	
			VirtualInspectionSW = 0;
		}
		VirtualDataRenewalSW = 0;		
	}
	else if (command == CMD_VIRTUAL_INSPECTION_REFRESH)
	{
//		memcpy(&CPBVirtualInspectionDataForRenewal, TcpPacketInfo.SmallDataAddress, sizeof(TCPBVirtualInspectionData));
		CPBVirtualInspectionDataForRenewal.Period = *((unsigned int *) TcpPacketInfo.SmallDataAddress); 
		CPBVirtualInspectionDataForRenewal.CameraMask = *((unsigned int *) TcpPacketInfo.SmallDataAddress + 1);
		CPBVirtualInspectionDataForRenewal.EnabledSPB =  *((unsigned int *) TcpPacketInfo.SmallDataAddress + 2); 
		CPBVirtualInspectionDataForRenewal.ProcessOption =  *((unsigned int *) TcpPacketInfo.SmallDataAddress + 3);
		VirtualDataRenewalSW = 1;		
	}
	else if (command == CMD_HPI_TEST_RESULT)
	{
		memcpy(GlobalSysResultBuffer, &HPITestData, sizeof(THPITestData));
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)GlobalSysResultBuffer;
		TcpPacketInfo.ResultSmallDataSize = sizeof(THPITestData);
	}
	else if (command == CMD_HPI_PROTOCOL_TEST)
	{
		unsigned int func;
		unsigned int cpbIndex;
		func = *((unsigned int *) TcpPacketInfo.SmallDataAddress);
		cpbIndex = *((unsigned int *) TcpPacketInfo.SmallDataAddress + 1);
		if (func == 0 || func == 1)
		{
			HPIProtocolTestData.Func = func;
			HPIProtocolTestData.CPBIndex = cpbIndex;
		}
		else if (func == 2)
		{
			TcpPacketInfo.ResultSmallDataAddress = (unsigned char *) &HPIStat;
			TcpPacketInfo.ResultSmallDataSize = sizeof(THPIStat);
		}
		else if (func == 3)
		{
			memset(&HPIStat, 0, sizeof(THPIStat));
		}
	}
	else if (command == CMD_READ_CPB_IMAGE)
	{
		int requestNum;
		int cpbIndex;
		int currentTime;
		requestNum = *((int *) TcpPacketInfo.SmallDataAddress);
		cpbIndex = *((int *) TcpPacketInfo.SmallDataAddress + 1);

		//memset(CPBDataBuffer, 0, 640 * 480 * 5);
		
		currentTime = Board50usTimer;
		Request_ReceiveData(IND_CPB_IMAGE, CPBDataBuffer,
			640 * 480 * 3, cpbIndex);

		//while(currentTime == Board50usTimer);

		if (requestNum == 0 || requestNum == 2)
		{
			currentTime = Board50usTimer;
			Request_ReceiveData(IND_INSPECTION_IMAGE, CPBDataBuffer + 640 * 480 * 3,
				640 * 480, cpbIndex);

			while(currentTime == Board50usTimer);
		}
		else if (requestNum == 1)
		{
			currentTime = Board50usTimer;
			Request_ReceiveData(IND_INSPECTION_LABEL_IMAGE, CPBDataBuffer + 640 * 480 * 3,
				640 * 480 * 2, cpbIndex);

			while(currentTime == Board50usTimer);
		}

		CPBDataBuffer[0] = 254;		

		TcpPacketInfo.ResultLargeDataAddress = CPBDataBuffer;
		if (requestNum == 0 || requestNum == 2)
		{
			TcpPacketInfo.ResultLargeDataSize = 640 * 480 * 4;
		}
		else if (requestNum == 1)
		{
			TcpPacketInfo.ResultLargeDataSize = 640 * 480 * 5;
		}
	}
	else if (command == CMD_VIRTUAL_INSPECTION_SET_IMAGE)
	{
		int camIndex = TcpPacketInfo.SmallDataAddress[0];
		memcpy(DummyImage[camIndex], TcpPacketInfo.LargeDataAddress, sizeof(DummyImage[0]));
	}
	else if (command == CMD_VIRTUAL_DEFECT_DATA)
	{
		if(VirtualProcessedDataCount)
		{			
			memcpy(&tempVirtualCPBProcessedData, &VirtualCPBProcessedData[VirtualProcessedDataCount], sizeof(TVirtualCPBProcessedData));
			memset(&VirtualCPBProcessedData[VirtualProcessedDataCount], 0, sizeof(TVirtualCPBProcessedData));

			TcpPacketInfo.ResultLargeDataAddress = (unsigned char *)&tempVirtualCPBProcessedData;
			TcpPacketInfo.ResultLargeDataSize = sizeof(TVirtualCPBProcessedData);		

			VirtualProcessedDataCount--;
		}
		else
		{
			VirtualCPBProcessedData[VirtualProcessedDataCount].ProcessingNumber = -1;
			
			TcpPacketInfo.ResultLargeDataAddress = (unsigned char *)&VirtualCPBProcessedData[VirtualProcessedDataCount];
			TcpPacketInfo.ResultLargeDataSize = sizeof(TVirtualCPBProcessedData);		
		}			
	}
	else if (command == CMD_VIRTUAL_DEBUGGING_DATA)
	{		
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&VirtualCPBStatus;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TVirtualCPBStatus) * SYSTEM_CPB_COUNT;					
	}
	else if (command == CMD_VIRTUAL_DEBUGGING_DATA2)
	{		
		int i = Virtual_SPB_GET_ProcessingData();
		
		if(i == -1)
		{
			tempVirtualSPBProcessedData.TabletNumber = 0x00FFFFFF;		
			TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&tempVirtualSPBProcessedData;
			TcpPacketInfo.ResultSmallDataSize = sizeof(TVirtualSPBProcessedData);					
		}
		else
		{
			VirtualDataLoadChk = 1;
			memcpy(&tempVirtualSPBProcessedData, &VirtualSPBProcessedData[i], sizeof(TVirtualSPBProcessedData));					
			memset(&VirtualSPBProcessedData[i], 0, sizeof(TVirtualSPBProcessedData));	
			//memset(&ProcessingTimeList[i], 0, sizeof(TProcessingTime));	
		
			TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&tempVirtualSPBProcessedData;
			TcpPacketInfo.ResultSmallDataSize = sizeof(TVirtualSPBProcessedData);			

			VirtualDataLoadChk = 0;
		}
	}
	else if (command == CMD_VIRTUAL_DEBUGGING_DATA3)
	{		
		int i = Virtual_SPB_GET_ProcessingData();

		if(i == -1)
		{
			SendData.TabletNumber = 0x00FFFFFF;
			SendData.currentTabletNum = VirtualTabletNumberSensor2;

			TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&SendData;
			TcpPacketInfo.ResultSmallDataSize = sizeof(SendData);					
		}
		else
		{
			VirtualDataLoadChk = 1;
			SendData.TabletNumber = VirtualSPBProcessedData[i].TabletNumber;
			SendData.Result = VirtualSPBProcessedData[i].Result;
			SendData.CapturedTime[0] = VirtualSPBProcessedData[i].CapturedTime[0];
			SendData.CapturedTime[1] = VirtualSPBProcessedData[i].CapturedTime[1];
			SendData.CapturedTime[2] = VirtualSPBProcessedData[i].CapturedTime[2];
			SendData.CapturedTime[3] = VirtualSPBProcessedData[i].CapturedTime[3];
			SendData.currentTabletNum = VirtualTabletNumberSensor2;

			memset(&VirtualSPBProcessedData[i], 0, sizeof(TVirtualSPBProcessedData));	
			//memset(&ProcessingTimeList[i], 0, sizeof(TProcessingTime));	
		
			TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&SendData;
			TcpPacketInfo.ResultSmallDataSize = sizeof(SendData);			

			VirtualDataLoadChk = 0;
		}
	}
	else if (command == CMD_VIRTUAL_DEBUGGING_DATA4)
	{
		VirtualInspectionSWFromHCB = 1;		
	}	
	else if (command == CMD_VIRTUAL_DEBUGGING_DATA5)
	{
		VirtualInspectionSWFromHCB = 0;
	}	
	else if (command == CMD_VERSION_INFO)
	{
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&ProgramVersion;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TProgramVersion);
	}
	else if (command == CMD_FPGA_VERSION_INFO)
	{
#ifdef FPGA220
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&FPGAnewVersion2;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TSPBFPGAVersion);
#else
		// sjm Chg 
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&SPBFPGAVersion;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TSPBFPGAVersion);
#endif		
		//t1 = FPGAnewVersion2.VersionH & 0xff;
		//t2 = FPGAnewVersion2.VersionL & 0xff;
		//ErrorUnit_Put(BoardID, ERROR_TYPE_MESSAGE, ERROR_CODE_CPB_PROCESS_TIMEOUT, t1, t2,300); //sjm teest
	}	
	else if (command == CMD_READ_COMPATIBILITY)
	{
		int cpbIndex;
		TCPBCompatibility CPBCompatibility;
		for (cpbIndex = 0; cpbIndex < SYSTEM_CPB_COUNT; cpbIndex++)
		{
			if (!CPBStatus[cpbIndex].IsDown)
			{
				if (Request_ReceiveData(IND_READ_COMPATIBILITY, &CPBCompatibility, sizeof(TCPBCompatibility), cpbIndex))
				{
					SPBCompatibility.CPBAlgMajorVersion = CPBCompatibility.AlgMajorVersion;
					SPBCompatibility.CPBAlgMinorVersion = CPBCompatibility.AlgMinorVersion;
					SPBCompatibility.CPBAlgReleaseDate = CPBCompatibility.AlgReleaseDate;
					SPBCompatibility.CPBAlgTargetSystem = CPBCompatibility.AlgTargetSystem;
					break;
				}
				else
				{
					SPBCompatibility.CPBAlgMajorVersion = 0;
					SPBCompatibility.CPBAlgMinorVersion = 0;
					SPBCompatibility.CPBAlgReleaseDate = 0;
					SPBCompatibility.CPBAlgTargetSystem = 0;
				}
			}
		}

		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&SPBCompatibility;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TSPBCompatibility);
	}	
	else if (command == CMD_ECHO)
	{
		TcpPacketInfo.ResultSmallDataAddress = TcpPacketInfo.SmallDataAddress;
		TcpPacketInfo.ResultSmallDataSize = TcpPacketInfo.SmallDataSize;
		TcpPacketInfo.ResultLargeDataAddress = TcpPacketInfo.LargeDataAddress;
		TcpPacketInfo.ResultLargeDataSize = TcpPacketInfo.LargeDataSize;
	}
	else if(command == CMD_LASER_MCBSP_START)	
	{
		test_Laser_MC_Status = 1;
		test_Laser_Mc_Period = *((unsigned int *) TcpPacketInfo.SmallDataAddress);
		test_Laser_Mc_Packet_Period = *(unsigned int *) (TcpPacketInfo.SmallDataAddress + 4);
		test_Laser_MC_Count = 0;
	}
	else if(command == CMD_LASER_MCBSP_STOP)	
	{
		test_Laser_MC_Status = 0;
		ErrorUnit_Put(BoardID, ERROR_TYPE_DEBUG, ERROR_CODE_PROCESS_RUNTIME, 111,222, test_Laser_MC_Count);
		test_Laser_MC_Count = 0;
	}	
	else if(command == CMD_SPB_THREED_SENSORMODE_ON)	
	{	
		int trigFreq, camIndex, calibrationMode;
		camIndex =  *((int *) TcpPacketInfo.SmallDataAddress);
		trigFreq =  *((int *) TcpPacketInfo.SmallDataAddress + 1);
		calibrationMode =  *((int *) TcpPacketInfo.SmallDataAddress + 2);

		EnabledThreeDCameraSensor(camIndex, trigFreq, calibrationMode);
	}
	else if(command == CMD_SPB_THREED_SENSORMODE_OFF)	
	{
		TabletCapture_Stop();
	}		
//20201106 cjg added 3d camera param
	else if(command == CMD_3D_CAMERA_CAL_OFFSET_READ)
	{	
		Camera3D_Calibration_Offset_Read(&Camera3D_OffsetParamData);
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&Camera3D_OffsetParamData;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TCamera3D_CalOffsetParam);
	}
	else if(command == CMD_3D_CAMERA_CAL_OFFSET_WRITE)
	{	
		TCamera3D_CalOffsetParam *TempCameraOffsetParamData;
		TempCameraOffsetParamData = (TCamera3D_CalOffsetParam *)TcpPacketInfo.SmallDataAddress;
		Camera3D_Calibration_Offset_Write(TempCameraOffsetParamData);
	}
	else if(command == CMD_3D_CAMERA_CAL_COG_READ)
	{	
		Camera3D_Calibration_COG_Read(&Camera3D_COGParamData);
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&Camera3D_COGParamData;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TCamera3D_CalCOGParam);
	}
	else if(command == CMD_3D_CAMERA_CAL_COG_WRITE)
	{
		TCamera3D_CalCOGParam *TempCameraCOGParamData;
		TempCameraCOGParamData = (TCamera3D_CalCOGParam *)TcpPacketInfo.SmallDataAddress;
		Camera3D_Calibration_COG_Write(TempCameraCOGParamData);
	}
	else if(command == CMD_CAMERA_VERSION)
	{
		int result;
		int camIndex;
		
		camIndex = *(int *)TcpPacketInfo.SmallDataAddress;
		CamVerData.Cam_Index = camIndex; 

		result = GetCamVersion(camIndex, &CamVerData.Cam_Ver_Major, &CamVerData.Cam_Ver_Minor);

		if(result < 0)
		{
			 CamVerData.Cam_Ver_Major = 0xFF;
			 CamVerData.Cam_Ver_Minor = 0xFF;
		}
		
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&CamVerData;
		TcpPacketInfo.ResultSmallDataSize = sizeof(T3DCameraVersion);			
	}
	else if (command == CMD_SET_CAMERA_ADC_RESOLUTION)
	{
		T3DCamera_ADC_Resolution *TmpCam_ADC_ResData;
		TmpCam_ADC_ResData = (T3DCamera_ADC_Resolution *)TcpPacketInfo.SmallDataAddress;
		Cam_ADC_Resolution_Write(TmpCam_ADC_ResData);
	}
	else if (command == CMD_GET_CAMERA_ADC_RESOLUTION)
	{
		int result;
		int camIndex;
		
		camIndex = *(int *)TcpPacketInfo.SmallDataAddress;
		Cam_ADC_ResolutionData.Cam_Index = camIndex; 

		result = Get3D_ADC_CamResolution(camIndex, &Cam_ADC_ResolutionData.Cam_ADC_Resolution);

		if(result < 0)
		{
			 Cam_ADC_ResolutionData.Cam_ADC_Resolution = 5;//0xFF;
		}
		
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&Cam_ADC_ResolutionData;
		TcpPacketInfo.ResultSmallDataSize = sizeof(T3DCamera_ADC_Resolution);	
	}
	else if (command == CMD_CLEAR_RT_MARKING_INFO)
	{
		RealtimeImageStartQueue = RealtimeImageEndQueue = 0;
		ImageControlInterval = 1;
	}
	else if (command == CMD_REFRESH_RT_IMG_INTERVAL)
	{
		int nInterval;
		nInterval = *(int *)TcpPacketInfo.SmallDataAddress;

		ImageControlInterval = nInterval;
	}	
	else if (command == CMD_CHK_CAM_TIME_OUT)
	{
		//Function
		CheckCamTimeOut.CamTimeOutStauts = NFACmeraBootCheck();
		TcpPacketInfo.ResultSmallDataAddress = (unsigned char *)&CheckCamTimeOut;
		TcpPacketInfo.ResultSmallDataSize = sizeof(TCheckCamTimeOut);
	}		
	if(command != 0)
		TcpPacketInfo.Status = SERVER_STATUS_SEND;	
}
