#include "PalmType.h"
#include "Palm1lib.h"
#include "p_tcpip.h"
#include "my_iax2.h"
#include "p_iax2.h"
#include "v_task.h"
#include "port.h"

static XSHORT _iIeLen;
static PXCHAR _pIeData;

static CCHAR _cIaxFrame[] = "IAX frame: ";
static CCHAR _cIaxFrameType[][8] = {"DTMF", "VOICE", "VIDEO", "CONTROL", "NULL", "IAX", "TEXT", "IMAGE", "HTML"};
static CCHAR _cIaxCommand[] = "IAX command: ";
static CCHAR _cIaxCommandType[][10] = 
{
	"NEW", "PING", "PONG", "ACK", "HANGUP", "REJECT", "ACCEPT", "AUTHREQ", 
	"AUTHREP", "INVAL", "LAGRQ", "LAGRP", "REGREQ", "REGAUTH", "REGACK", 
	"REGREJ", "REGREL", "VNAK", "DPREQ", "DPREP", "DIAL", "TXREQ", "TXCNT", 
	"TXACC", "TXREADY", "TXREL", "TXREJ", "QUELCH", "UNQUELCH", "POKE", 
	"PAGE", "MWI", "UNSUPPORT", "TRANSFER", "PROVISION", "FWDOWNL", "FWDATA"
};

static CCHAR _cIaxControl[] = "IAX control: ";
static CCHAR _cIaxControlType[][16] = 
{
	"HANGUP", "RING", "RINGING", "ANSWER", "BUSY", "TAKE OFF HOOK", "OFF HOOK", 
	"CONGESTION", "FLASH", "WINK", "OPTION", "KEY RADIO", "UNKEY RADIO", "CALL PROGRESS",
	"CALL PROCEEDING", "HOLD", "UNHOLD"
};

void iax2_ie_start()
{
	_iIeLen = 0;
	_pIeData = (PXCHAR)(Adapter_pSendUdpData + IAX_FULLFR_DATA);
}

void iax2_ie_add_xraw(UCHAR iType, PXCHAR pData, UCHAR iLen)
{
	_pIeData[_iIeLen] = iType;
	_iIeLen ++;
	_pIeData[_iIeLen] = iLen;
	_iIeLen ++;
	if (iLen)
	{
		p_memcpy_x2x((PXCHAR)(_pIeData + _iIeLen), pData, iLen);
		_iIeLen += iLen;
	}
}

void iax2_ie_add_craw(UCHAR iType, PCCHAR pData, UCHAR iLen)
{
	_pIeData[_iIeLen] = iType;
	_iIeLen ++;
	_pIeData[_iIeLen] = iLen;
	_iIeLen ++;
	if (iLen)
	{
		p_memcpy_c2x((PXCHAR)(_pIeData + _iIeLen), pData, iLen);
		_iIeLen += iLen;
	}
}


void iax2_ie_add_byte(UCHAR iType, UCHAR iData)
{
	_pIeData[_iIeLen] = iType;
	_iIeLen ++;
	_pIeData[_iIeLen] = 1;
	_iIeLen ++;
	_pIeData[_iIeLen] = iData;
	_iIeLen ++;
}

void iax2_ie_add_short(UCHAR iType, USHORT iData)
{
	XCHAR pBuf[2];
	USHORT2PXCHAR(iData, pBuf);
	iax2_ie_add_xraw(iType, pBuf, 2);
}

void iax2_ie_add_long(UCHAR iType, ULONG iData)
{
	XCHAR pBuf[4];
	ULONG2PUCHAR(iData, (PUCHAR)pBuf);
	iax2_ie_add_xraw(iType, pBuf, 4);
}

void iax2_ie_add_xstr(UCHAR iType, PXCHAR pStr)
{
	iax2_ie_add_xraw(iType, pStr, p_strlen_x(pStr));
}

void iax2_ie_add_cstr(UCHAR iType, PCCHAR pStr)
{
	iax2_ie_add_craw(iType, pStr, p_strlen_c(pStr));
}

USHORT iax2_ie_get_len()
{
	return _iIeLen;
}


void iax2_debug_string(UCHAR iType, UCHAR iSubClass)
{
	XCHAR pDebugString[32];

	pDebugString[0] = 0;
	if (iType >= AST_FRAME_DTMF && iType <= AST_FRAME_HTML)
	{
		p_strcpy_c2x(pDebugString, _cIaxFrame);
		p_strcat_c2x(pDebugString, _cIaxFrameType[iType-1]);
		DebugString(pDebugString);

		if (iType == AST_FRAME_IAX)
		{
			if (iSubClass >= IAX_COMMAND_NEW && iSubClass <= IAX_COMMAND_FWDATA)
			{
				p_strcpy_c2x(pDebugString, _cIaxCommand);
				p_strcat_c2x(pDebugString, _cIaxCommandType[iSubClass-1]);
				DebugString(pDebugString);
			}
			else
			{
				DebugCString((PCCHAR)"IAX command: undefined");
			}
		}
		else if (iType == AST_FRAME_CONTROL)
		{
			if (iSubClass >= AST_CONTROL_HANGUP && iSubClass <= AST_CONTROL_UNHOLD)
			{
				p_strcpy_c2x(pDebugString, _cIaxControl);
				p_strcat_c2x(pDebugString, _cIaxControlType[iSubClass-1]);
				DebugString(pDebugString);
			}
		}

	}
	else
	{
		DebugCString((PCCHAR)"IAX frame: undefined");
	}
}
