#include "./include/sip_pub.h"
#include "./include/sip.h"
#include "./include/sip_const.h"
#include "./include/sip_struct.h"
#include "./include/sip_ext.h"
#include "./include/sip_msg.h"
#include "./include/sip_msg_encode.h"
#include "./include/sip_debug.h"

int	sip_transport_send_udp_msg()
{
	int ret, len;
	
	sipUdpMsgSdBuf[SIP_MAX_UDP_MSG_LEN - 1] = '\0';
	len = strlen(sipUdpMsgSdBuf);
	if (len >= SIP_MAX_UDP_MSG_LEN)
		return -1;
	
	ret = sendto(sipUdpSocketFd, sipUdpMsgSdBuf, len, 0, (struct sockaddr *) &sipDstInAddr, sizeof(sipDstInAddr));
	
	if (ret >= 0)
	{
		sipUdpMsgSdBuf[len] = '\0';
		if ((sipMonitorFg & MONITOR_SIP_MSG) == MONITOR_SIP_MSG)
		{
			sprintf(sipAsciTempBuf, "Send SIP Msg (UDP) ===> dest port: %d, dest ipV4: %s\r\n", ntohs(sipDstInAddr.sin_port), inet_ntoa(sipDstInAddr.sin_addr));
			sip_asciout_proc(sipAsciTempBuf);
			sip_asciout_proc(sipUdpMsgSdBuf);
			sip_asciout_proc("\r\n");
		}
	}
	else
	{
           sprintf(sipAsciTempBuf, "Send SIP Msg (UDP) Failed ===> dest port: %d, dest ipV4: %s\r\n", ntohs(sipDstInAddr.sin_port), inet_ntoa(sipDstInAddr.sin_addr));
           sip_log_err(sipAsciTempBuf);
	}
	
	return ret;
}

int sip_transport_recv_udp_msg()
{
	int	i, len, addrLen = sizeof(struct sockaddr);
	
	for (i = 0; i < SIP_MAX_UDP_MSG_GET_TIMES; i++)
	{
		len = recvfrom(sipUdpSocketFd, sipUdpMsgRvBuf, SIP_MAX_UDP_MSG_LEN, 
                   			0, (struct sockaddr *)&sipSrcInAddr, &addrLen);
		if (len < 0)
			break;
		
		if (len >= SIP_MAX_UDP_MSG_LEN)
			continue;
		
		sipUdpMsgRvBuf[len] = '\0';
		
		memset((BYTE *)&sipRecvMsg, 0, sizeof(SIP_API_STRUCT));
		
		sipRecvMsg.sipTransAddr.type = 0;			// ipv4 & udp
		sipRecvMsg.sipTransAddr.port = ntohs(sipSrcInAddr.sin_port);
		sipRecvMsg.sipTransAddr.addr.ipV4 = sipSrcInAddr.sin_addr.s_addr;
		
		if ((sipMonitorFg & MONITOR_SIP_MSG) == MONITOR_SIP_MSG)
		{
			sprintf(sipAsciTempBuf, "Receive SIP Msg (UDP) <=== src port: %d, src ipV4: %s\r\n", sipRecvMsg.sipTransAddr.port, inet_ntoa(sipSrcInAddr.sin_addr));
			sip_asciout_proc(sipAsciTempBuf);
			sip_asciout_proc(sipUdpMsgRvBuf);
			sip_asciout_proc("\r\n");
		}
		
		sip_recv_msg_handling(sipUdpMsgRvBuf, len, -1);
	}

	return 0;
}

/*int sip_transport_recv_tcp_msg()
{
	int i, newSock, len;
	struct sockaddr_in remote_addr;

    for (i = 0; i < SIP_MAX_NUM_OF_TCP_SOCK; i++)
    {
        if (sipTcpSock[i].flag != 1)
	        continue;

        len = recv(sipTcpSock[i].sendRecvSock, sipTcpMsgRvBuf, SIP_MAX_TCP_MSG_LEN, 0);

	    if (len < 0) 
            break;

        sip_recv_msg_handling(sipTcpMsgRvBuf, len, i);
    }

    len = sizeof(remote_addr);
    bzero((char *)&remote_addr, len);

    if ((newSock = accept(sipTcpServerSocketFd, (struct sockaddr *)&remote_addr, (int *)&len)) < 0)
        return 0;

    for (i = 0; i < SIP_MAX_NUM_OF_TCP_SOCK; i++)
    {
        if (sipTcpSock[i].flag == 1)
            continue;

		sipTcpSock[i].sendRecvSock = newSock;
        memcpy(&sipTcpSock[i].remoteAddr, &remote_addr, sizeof(struct sockaddr_in));

        len = recv(sipTcpSock[i].sendRecvSock, sipTcpMsgRvBuf, SIP_MAX_TCP_MSG_LEN, 0);

        if (len < 0) 
            break;

        sip_recv_msg_handling(sipTcpMsgRvBuf, len, i);
    }

    return 0;
}*/

int sip_transport_encode_trans_msg(SIP_TRANSACTION     *trans, SIP_API_STRUCT *sipApiMsg)
{
	char dest[SIP_MAX_UDP_MSG_LEN] = "";
	
	if (sip_transport_encode_start_line(dest, sipApiMsg) < 0)
		return -1;
	
	if (sip_transport_encode_headers(dest, sipApiMsg) < 0)
		return -1;
	
	if (sip_transport_encode_body(dest, sipApiMsg) < 0)
		return -1;

       memcpy(&trans->transSdMsg.sipSdAddr, &sipApiMsg->sipTransAddr, sizeof(SIP_TRANSPORT_ADDR));

       strcpy(trans->transSdMsg.sdMsg, dest);
       trans->transSdMsg.sdMsg[SIP_MAX_UDP_MSG_LEN - 1] = '\0';

	return 0;
}

int sip_transport_encode_msg(SIP_API_STRUCT *sipApiMsg)
{
	char *dest = sipUdpMsgSdBuf;
	
	strcpy(dest, "");
	
	if (sip_transport_encode_start_line(dest, sipApiMsg) < 0)
		return -1;
	
	if (sip_transport_encode_headers(dest, sipApiMsg) < 0)
		return -1;
	
	if (sip_transport_encode_body(dest, sipApiMsg) < 0)
		return -1;
	
	if (sip_transport_set_addr(&sipDstInAddr, sipApiMsg) < 0)
		return -1;
	
	return 0;
}

int sip_transport_send_trans_msg(SIP_TRANS_SD_MSG *transSdMsg)
{
    strcpy(sipUdpMsgSdBuf, transSdMsg->sdMsg);

    if (sip_transport_set_sd_addr(&sipDstInAddr, &transSdMsg->sipSdAddr) < 0)
        return -1;

    sip_transport_send_udp_msg();

    return 0;
}

int	sip_transport_send_msg(SIP_API_STRUCT *sipApiMsg)
{
	if ((sipApiMsg->sipApiType != SIP_API_REQ_MSG) 
		&& (sipApiMsg->sipApiType != SIP_API_RES_MSG))
		return -1;
	
	if (sip_transport_encode_msg(sipApiMsg) < 0)
		return -1;
	
	sip_transport_send_udp_msg();
	
	return 0;
}

void sip_transport_proc()
{
	sip_transport_recv_udp_msg();
//    sip_transport_recv_tcp_msg();
}
