#include "p_apps.h"
#include "v_task.h"

#define TCP_UPGRADE_SIZE	128
#define UPGRADE_TIME_OUT	15

// Tcp connection data

static XCHAR _iCurMsgPos;
static XCHAR _iCodePage;
static BOOLEAN _bFirstTime;

void UpgradeInitialize()
{
	TcbInit(TCP_UPGRADE_PORT, UPGRADE_TIME_OUT, UPGRADE_SDRAM_LO);

	// protocol init
	_iCurMsgPos = 0;
	_iCodePage = 0xff;
	_bFirstTime = TRUE;
}

void _CheckSdramLimit(ULONG lLen, BOOLEAN bCheck)
{
	if (bCheck && lLen > FILE_ONE_PAGE_SIZE)
	{
		OnReboot();
	}
	UpgradeInitialize();	// re-initialize all
}

void _HandleUpgradeData()
{
	DCHAR iFirst;

	iFirst = X_VAL(Adapter_pReceiveTcpData, 0);

	if (Adapter_iReceiveLen == 1)	// This is the indication of which page to erase
	{
		_iCodePage = iFirst;
		_iCurMsgPos = 1;
		X_VAL(Adapter_pSendTcpData, 0) = 0xff;
	}
	else if (Adapter_iReceiveLen == 2)	// Request data from sdram
	{
		if (_bFirstTime)
		{
			Ac97Stop();
			SoloFileCloseRead();

			if (iFirst == 'd')	// data hint
			{
				SoloFileOpen(FILE_OUT_SDRAM_HI, FALSE, FILE_READ_MAX_SIZE);
			}
			else if (iFirst == 's')	// settings hint
			{
				SysWriteOptions();
				SoloFileOpen(OPTIONS_SDRAM_HI, FALSE, FILE_ONE_PAGE_SIZE);
			}
			_bFirstTime = FALSE;
		}
		SoloFileRead((PXCHAR)Adapter_pSendTcpData, TCP_UPGRADE_SIZE);
		_iCurMsgPos = TCP_UPGRADE_SIZE;
	}
	else	// Data to sdram
	{
		if (_bFirstTime)
		{
			CreateUpgradeFile();
			_bFirstTime = FALSE;
		}
		SoloFileWrite((PXCHAR)Adapter_pReceiveTcpData, TCP_UPGRADE_SIZE);
//		DisplayFileStatus();
		_iCurMsgPos = 1;
		X_VAL(Adapter_pSendTcpData, 0) = 0xff;
	}
}

BOOLEAN UpgradeRun()
{
	DCHAR iPage;
	DLONG lLen;

	if (!TcbRun(UPGRADE_SDRAM_LO))	return FALSE;
/*	if (Tcp_bAcceptEvent)
	{
		Tcp_bAcceptEvent = FALSE;
	}
*/
	if (Tcp_bConnectEvent)
	{
		Tcp_bConnectEvent = FALSE;
		_iCodePage = 0xff;
	}
    if (Tcp_bDataEvent)
    {
        // Handle upgrade data here
		_HandleUpgradeData();
		Tcp_bDataEvent = FALSE;
    }
	TcpSend(_iCurMsgPos);
	_iCurMsgPos = 0;

    if (Tcp_bCloseEvent)
    {
		Tcp_bCloseEvent = FALSE;
		lLen = SoloFileClose();
		iPage = _iCodePage;
		if (iPage == 0xff)
		{
			goto End;
		}
		else if (iPage == PROGRAM_UPGRADE_PAGE)
		{
			if (!IsFirmwareLenOK(lLen))	goto End;
		}
		else if (iPage == OPTIONS_UPGRADE_PAGE)
		{
			CopyFileToOption(16, 0);
		}
		else if (iPage == ALTERNATE_SETTING_UPGRADE_PAGE)
		{
			CopyFileToOption(8, ALTERNATE_SETTING_LO);
			iPage = OPTIONS_UPGRADE_PAGE;
		}
		else if (iPage == MAP_UPGRADE_PAGE)
		{
			CopyFileToOption(8, DIAL_MAP_LO);
			iPage = OPTIONS_UPGRADE_PAGE;
		}
#ifdef GUI_UPGRADE_RING
		else if (iPage == RING_UPGRADE_PAGE)
		{
			OnUpdateRingFile(lLen);
		}
#endif
		OnSwitchUpgrade(iPage);
End:
		_CheckSdramLimit(lLen, (BOOLEAN)((iPage == 0xff) ? FALSE : TRUE));
	}

    if (Tcp_bResetEvent)
    {
		Tcp_bResetEvent = FALSE;
		_CheckSdramLimit(SoloFileClose(), TRUE);
	}
	return TRUE;
}

void UpgradeHandleTimer()
{
	if (TcbHandleTimer(UPGRADE_SDRAM_LO))
	{
		return;
	}

//	DebugCString((PCCHAR)"Upgrade timer fail");

	// Handle time out failure
	_CheckSdramLimit(SoloFileClose(), TRUE);
}

