#include "debug.h"
#include "p_util.h"
#include "p_rtp.h"
#include "p_sdp.h"
#include "p_http.h"

//#define MAX_PACKET_LEN		1272

#define SIP_ARP_IDLE		0
#define SIP_ARP_CALL		1
#define SIP_ARP_REG			2

#define SIP_AUTH_MAX_RETRY	2

#define SIP_AUTH_REG		0
#define SIP_AUTH_CALL		1
#define SIP_AUTH_ALL		2

#define SIP_REQ_INVITE		0
#define SIP_REQ_ACK			1
#define SIP_REQ_OPTIONS		2
#define SIP_REQ_BYE			3
#define SIP_REQ_CANCEL		4
#define SIP_REQ_REGISTER	5
#define SIP_REQ_REFER		6
#define SIP_REQ_NOTIFY		7
#define SIP_REQ_INFO		8
#define SIP_REQ_PRACK		9
#define SIP_REQ_UPDATE		10
#define SIP_REQ_MESSAGE		11
#define SIP_REQ_NUMBER		12
#define SIP_REQ_UNKNOWN		99

#define SIP_RESP_UNKNOWN		0
#define SIP_RESP_PROVISIONAL	1
#define SIP_RESP_SUCCESSFUL		2
#define SIP_RESP_REDIRECTION	3
#define SIP_RESP_REQUEST_FAIL	4
#define SIP_RESP_SERVER_FAIL	5	
#define SIP_RESP_GLOBAL_FAIL	6	

#define SIP_CTYPE_SDP		0
#define SIP_CTYPE_SIPFRAG	1
#define SIP_CTYPE_DTMF		2

#define SIP_CALL_NUMBER		2

#define CALL_INFO_CUR_SEQ	0
#define CALL_INFO_INV_SEQ	1
#define CALL_INFO_INV_TRANS	2
#define CALL_INFO_STATE		3
#define CALL_INFO_FLAG		4
#define CALL_INFO_LEN		5

#define TAG_LABEL_LEN		4
#define SIP_VER_LABEL_LEN	8

#define EVENT_REFER_LABEL_LEN		5
#define EVENT_MESSAGE_LABEL_LEN		15

#define SIP_TRANS_ERROR		0xff

#define SIP_STUN_TASK_IDLE		0
#define SIP_STUN_TASK_REG		1
#define SIP_STUN_TASK_CALL		2
#define SIP_STUN_TASK_ANSWER	3

#define REL100_DATA_RSEQ	0
#define REL100_DATA_CSEQ	4
#define REL100_DATA_LEN		8

#define SIP_EVENT_REFER		0
#define SIP_EVENT_MESSAGE	1

extern CCHAR _cCallId[];
extern CCHAR _cContact[];
extern CCHAR _cCSeq[];
extern CCHAR _cFrom[];
extern CCHAR _cTo[];
extern CCHAR _cVia[];
extern CCHAR _cContentType[];
extern CCHAR _cAllow[]; 
extern CCHAR _cExpires[];
extern CCHAR _cReferTo[];
extern CCHAR _cReferredBy[];
extern CCHAR _cReplaces[];
extern CCHAR _cRequire[];
extern CCHAR _cRAck[];
extern CCHAR _cRSeq[];
extern CCHAR _cTag[];
extern CCHAR _c100rel[];
extern CCHAR _cRecordRoute[];
extern CCHAR _cRoute[];
extern CCHAR _cSupported[];
extern CCHAR _cEvent[];

extern CCHAR _cEventRefer[];
extern CCHAR _cEventMessage[];

extern DCHAR Sip_iRecvViaNum;
extern PXCHAR_D Sip_pCallData;
extern DCHAR Sip_iBaseIndex;
extern XSHORT Sip_iSendLen;

extern DCHAR Sip_iRecvMethod;
extern PXCHAR Sip_pDataOut;
extern CCHAR _cSipColon[];
extern CCHAR _cMethod[][9];
extern CCHAR _cMethodLen[];
extern CCHAR Sip_cContentType[][23];

extern CCHAR _cSipVer[];
extern DCHAR Sip_iBodyLines;

extern BOOLEAN Sip_bUsingUdp;
extern DCHAR Sip_iCurCall;
extern DCHAR Sip_iMsgIndex;


// sip_acc.c
void SipSaveInv(UCHAR iIndex);
void SipLoadInv(UCHAR iIndex);
void SipFillInv(BOOLEAN bReInvite);
void SipFillAck(BOOLEAN bSuccess);
void SipFillBye();
void SipFillCancel();
void SipFillRefer();
void SipFillInfo(UCHAR iKey);
void SipFillNotify(USHORT iCode);
void SipFillPrack();
void SipFill2xxSdp(BOOLEAN bOffer);
void SipFillFinalResp(USHORT iResp, UCHAR iTagIndex);
void SipFill180(UCHAR iTagIndex, UCHAR iRSeqIndex);
void SipOptionsResp(USHORT iResp);

// sip_auth.c
void SipGenAuth(UCHAR iMethod, UCHAR iUriIndex, UCHAR iAuthIndex, UCHAR iAuthType);
void SipFillAuth();
void SipCopyAuth(UCHAR iWWWAuth, UCHAR iProxyAuth);

// sip_call.c
BOOLEAN SipCallIsIdle(UCHAR iCallIndex);
BOOLEAN SipCallAllIdle();
BOOLEAN SipMatchCall(UCHAR iCallIndex);
UCHAR SipMatchInvTrans(UCHAR iTransNo);
void SipSetCallContext(UCHAR iCallIndex);
void SipCallEnd(UCHAR iType);
void SipInitCall();
void SipStartCaller();
void SipTransferNotify(USHORT iResp);
void SipTransfertoClear();
void SipCallInvResp(USHORT iResp);
void SipCallHangup();
void SipStartCallee();
void SipCallInvReq();
void SipCallReinvReq();
void SipCallAckReq();
void SipCallByeReq();
void SipCallCanReq();
void SipCallRefReq();
void SipNotifyReq();
void SipMessageReq();
void SipCallInfoReq();
void SipCallPrackReq();
void SipCallUpdateReq();
void SipCallRefResp(USHORT iVal);
void SipCallByeResp(USHORT iVal);
void SipCallCancelResp(USHORT iVal);
void SipCallPrackResp(USHORT iVal);
void SipCallNotifyResp(USHORT iVal);
void SipAckFinalResp();
void SipSendFinalResp(UCHAR iTransNo, USHORT iResp);

// sip_comp.c
UCHAR SipGetMethod(PXCHAR pData);
PCCHAR SipGetRespCode(USHORT iResp);
PXCHAR SipGetLocalUser();
void SipAppendTag(UCHAR iTagIndex);
void SipEscapeStr(PXCHAR pDstStr, PXCHAR pSrcStr);
void SipNewNameUri(PXCHAR pDst, PXCHAR pNumber);
void SipNewIPUri(PXCHAR pDst, PXCHAR pIP, PXCHAR pNumber);
void SipNewReqNameUri(PXCHAR pDst, PXCHAR pNumber);
void SipNewReqIPUri(PXCHAR pDst, PXCHAR pIP);
void SipNewBranch(UCHAR iIndexLow);
void SipNewTag(UCHAR iIndexLow);
void SipNewCallId(UCHAR iDstIndex);
void SipNewLocalUri(UCHAR iDstIndex);
void SipFillVia(UCHAR iBranchIndex);
void SipFillFrom(UCHAR iUriIndex, UCHAR iTagIndex);
void SipFillTo(UCHAR iUriIndex, UCHAR iTagIndex);
void SipFillReferTo(UCHAR iUriIndex);
void SipFillReferredBy();
void SipFillCallId(UCHAR iCallIdIndex);
void SipFillReqLine(UCHAR iMethod, UCHAR iUriIndex);
void SipFillStatusLine(USHORT iResp);
void SipFillContact();
void SipFillFwdContact();
void SipFillCSeq(ULONG lSeq, UCHAR iMethod);
void SipFillMaxForwards();
void SipFillExpires(USHORT iVal);
void SipFillContentLength(USHORT iLen);
void SipFillContentType(UCHAR iType);
void SipFillAllow();
void SipFillUserAgent();
void SipFillAccept();
void SipFillSupported();
void SipFillRequire();
void SipFillProxyRequire();
void SipFillRAck(ULONG lRSeq, ULONG lCSeq);
void SipFillEvent(UCHAR iEventType);
void SipFillSdp(BOOLEAN bOffer);

// sip_core.c
PXCHAR SipGetLocalIP();
void SipGetTag(UCHAR iDstIndex, UCHAR iSrcIndex);
void SipRemoveTag(UCHAR iDstIndex, UCHAR iSrcIndex);
BOOLEAN SipGetUri(PXCHAR pDst, UCHAR iSrcIndex);
void SipGetRemoteId(UCHAR iSrcIndex);
USHORT SipGetIPPort(PXCHAR pDstIP, UCHAR iSrcIndex);
USHORT SipGetSentby(UCHAR iSrcIndex);
void SipGetRouteSet(UCHAR iDstIndex, UCHAR iSrcIndex);
BOOLEAN SipGetReplaces(UCHAR iDstIndex, UCHAR iSrcIndex);
void SipAddBracket(UCHAR iDstIndex, UCHAR iSrcIndex);
void SipRemoveBracket(UCHAR iDstIndex, UCHAR iSrcIndex);
BOOLEAN SipParse100rel(UCHAR iIndex);
void SipInitRecv();
void SipRunData();

// sip_reg.c
void SipStartReg();
void SipRegStartup();
void SipRegHandleTxError();
void SipRegHandleResp(USHORT iResp);
void SipRegHandleTimer();

// sip_rx.c
UCHAR SipRxAlloc();
void SipRxDealloc(UCHAR iRxIndex);
void SipRxStartup();
void SipRxSave(UCHAR iRxIndex);
void SipRxSend(UCHAR iRxIndex, UCHAR iUdpIndex);

// sip_sdp.c
void SipInitSdp();
void SipSaveSdp(UCHAR iDstIndex);
void SipLoadSdp(UCHAR iSrcIndex);
USHORT SipNewSdp(UCHAR iIndexLow, BOOLEAN bOffer);
BOOLEAN SipSdpParse(UCHAR iDstIndex);

// sip_stun.c


// sip_trans.c
void SipTransStartup();
UCHAR SipAllocTrans(BOOLEAN bClient);
void SipCtSendReq(UCHAR iMethod, UCHAR iUdpIndex, UCHAR iTransNo);
void SipCtAckInv(UCHAR iTransNo);
void SipCtRecvResp(UCHAR iMethod, USHORT iResponse);
void SipCtHandleTimer();
void SipStSave(UCHAR iTransNo, UCHAR iMethod, UCHAR iUdpIndex);
void SipStRecvReq(UCHAR iMethod);
BOOLEAN SipStRecvAck(UCHAR iTransNo);
void SipStSendResp(UCHAR iTransNo, USHORT iResp);
void SipStHandleTimer();
void SipTransSetFlag100rel(UCHAR iTransNo);
void SipTransClearFlag100rel(UCHAR iTransNo);

// sip_tsp.c
void SipTspStartup();
//void SipCopyUdpHead(UCHAR iDstIndex, UCHAR iSrcIndex);
void SipUdpSend(UCHAR iHeadIndex);

// sip_tu.c
void SipUasInit100rel(UCHAR iRSeqIndex);
BOOLEAN SipUasCmp100rel();
void SipUacInit100rel();
BOOLEAN SipUacCmp100rel();
void SipTUHandleTxError(UCHAR iMethod, UCHAR iTransNo);
BOOLEAN SipTUHandleResp(UCHAR iMethod, USHORT iResp);
void SipTUHandleReq(UCHAR iMethod);

// sip_util.c
void SipNewToken(PXCHAR pToken, UCHAR iLen);
BOOLEAN SipCmpSdram(UCHAR iDstIndex, UCHAR iSrcIndex);
void SipCpySdram(UCHAR iDstIndex, UCHAR iSrcIndex);
PXCHAR SipStrChr(PXCHAR pString, UCHAR iChar);

