/*
 * Non-blocking TCP connect()
 *
 * 1. fcntl(*sockfd,F_SETFL,FNDELAY) to make connect return immediately(return value=EINPROGRESS)
 * 2. 
 *
 */
#include "include/tcp_client.h"
#include "include/smeg_pub.h"
#define	SMEG_DEBUG_ERROR			true
/* by simon at 23/9/27 */
//extern BYTE DEBUG_buf[6000];

/*
 * Syntax: tcp_tx_connect("127.0.0.1",25)
 * INPUT: Destination IP, Port
 */


int
tcp_send(int sockfd, byte *send_buffer, int send_buffer_size)
{
	return(send(sockfd, send_buffer, send_buffer_size, MSG_NOSIGNAL));
}

int
tcp_recv(int sockfd, byte *recv_buffer, int recv_buffer_size)
{
	return(read(sockfd, recv_buffer, recv_buffer_size));
}

int tcp_disconnect(int sockfd)
{
	return(close(sockfd));

}
/* --------------------------------------------- *
 * nonblocking_flag=0 for normal connect()
 * nonblocking_flag=1 for non-blocking connect()
 * --------------------------------------------- */
int tcp_tx_connect(int *sockfd, char *dest_ip, unsigned short int dest_port,int nonblocking_flag)
{
	int    ret;
	struct sockaddr_in serv_addr;
	int error = -1, len;
  	len = sizeof(int);

	memset((char *) &serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family      = AF_INET;
	serv_addr.sin_addr.s_addr = inet_addr(dest_ip);
	serv_addr.sin_port        = htons(dest_port);
	if(*sockfd <= 0)
	{
		if ( (*sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		{
			perror("socket");
			return(*sockfd);
		}
		else
		{
			fcntl(*sockfd, F_SETFL, O_NONBLOCK);
		}
	}
	
	if(connect(*sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
	{
		getsockopt(*sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
	    	if(error == 0) 
    			ret = -1;
	 	else
 			ret = -2;
	}
	else
	{ 
		smeg_print("\nconnect sockfd=%d\n", *sockfd);
		ret = 0;
	}
	
	return ret;
}

int tcp_socket(int *sockfd)
{
	if((*sockfd=socket(AF_INET,SOCK_STREAM,0))==-1) 
	{ 
		smeg_print("socket fail\n");
		printf("smeg socket fail\n");
		return 0;
	} 
	if(fcntl(*sockfd,F_SETFL,O_NONBLOCK)<0)
	{
		fprintf(stderr,"set nonblock failed\n");
	    return 0;
  	}
	smeg_print("\nsocket success\n");
	printf("smeg socket success\n");
	return 1;
}

int tcp_bind(int sockfd, struct sockaddr *my_addr, int addrlen)
{
	if(bind(sockfd, my_addr, addrlen)<0) 
	{ 
		sleep(60);
		if(bind(sockfd, my_addr, addrlen)<0) {
			smeg_print("bind fail\n");
			printf("smeg bind fail\n");
			return 0;
		}
	} 
	printf("smeg bind success\n");
	smeg_print("bind success\n");
	return 1;
}

int tcp_listen(int sockfd, int backlog)
{
	if(listen(sockfd,backlog)==-1) 
	{ 
		smeg_print("listen fail\n");
		printf("smeg listen fail\n");
		return 0;
	} 
	smeg_print("listen success\n");
	printf("smeg listen success\n");
	return 1;
}

int tcp_accept(int sockfd, struct sockaddr *addr,int *addrlen)
{
	return (accept(sockfd, addr, (size_t*)addrlen));
}








