#include "SiTCP.h"
 
//------------------------------------------------------------------------------------------------------ 
 
void SiTCPinit(){
 
        printf("SiTCP control --> Start.\n");  
        WORD wVersionRequested;
 
    WSADATA wsaData;
 
    int err;
 
 
 
/* Use the MAKEWORD(lowbyte, highbyte) macro declared in Windef.h */
 
    wVersionRequested = MAKEWORD(2, 2);
 
 
 
    err = WSAStartup(wVersionRequested, &wsaData);
 
    if (err != 0) {
 
        /* Tell the user that we could not find a usable */
 
        /* Winsock DLL.                                  */
 
        printf("WSAStartup failed with error: %d\n", err
);  
    }
 
};
 
//------------------------------------------------------------------------------------------------------ 
 
void SiTCPclose(){  
 
        WSACleanup();
 
        printf("SiTCPclose -> Done.\n");  
};
 
//------------------------------------------------------------------------------------------------------ 
 
int SiTCPSetIPPort(char* IpAddr, unsigned int tcp, unsigned int udp){
 
  sitcpIpAddr = IpAddr;
 
  if(tcp<=0 || 65535<=tcp || udp<=0 || 65535<=udp){
 
    if(tcp<=0 || 65535<=tcp){
 
                printf("error : invalid port : tcp = %u\n", tcp
);  
    }
 
    if(udp<=0 || 65535<=udp){
 
                printf("error : invalid port : udp = %u\n", udp
);  
    }
 
  }
 
  tcpPort = tcp;
 
  udpPort = udp;
 
  printf("SiTCP:IP Address = %s\n", sitcpIpAddr
);  
  printf("      TCP Port   = %u\n", tcpPort
);  
  printf("      UDP Port   = %u\n", udpPort
);  
  return 1;
 
}
 
//------------------------------------------------------------------------------------------------------ 
 
int SiTCPCreateTCPSock(){
 
  printf("Create socket for TCP...");  
  tcpsock = socket(AF_INET, SOCK_STREAM, 0);
 
  if(tcpsock < 0){
 
    printf("errno = %d\n", errno
);  
  }
 
  memset(&tcpAddr
, 0, sizeof(tcpAddr
));  
  tcpAddr.sin_family      = AF_INET;
 
  tcpAddr.sin_port        = htons(tcpPort);
 
  tcpAddr.sin_addr.s_addr = inet_addr(sitcpIpAddr);
 
 
 
  printf("  ->Trying to connect to %s ...\n", sitcpIpAddr
);  
  if(connect(tcpsock, (struct sockaddr *)&tcpAddr, sizeof(tcpAddr)) < 0){
 
    if(errno 
!= EINPROGRESS
) perror("TCP connection");  
    FD_ZERO(&rmask);
 
    FD_SET(tcpsock, &rmask);
 
    wmask = rmask;
 
    timeout.tv_sec = 3;
 
    timeout.tv_usec = 0;
 
    
 
    int rc = select(tcpsock+1, &rmask, NULL, NULL, &timeout);
 
    if(rc
<0) perror("connect-select error");  
    if(rc==0){
 
      puts("\n     =====time out !=====\n ");  
    }
 
    else{
 
      puts("\n     ===connection error===\n ");  
    }
 
  }  
 
  FD_ZERO(&readfds);
 
  FD_SET(tcpsock, &readfds);
 
  FD_SET(0, &readfds);
 
 
 
   puts("  ->Connect success!");  
 
 
   return 1;
 
 }
 
 //------------------------------------------------------------------------------------------------------  
 
 int SiTCPCreateUDPSock(){
 
   printf("Create socket for RBCP...");  
   udpsock = socket(AF_INET, SOCK_DGRAM, 0);
 
   //if(udpsock < 0){
 
        if(udpsock == INVALID_SOCKET){
 
     //perror("UDP socket");
 
     //printf("errno = %d | udpsock = %d\n", errno, udpsock);
 
     printf("errno = %d | udpsock = %d\n", WSAGetLastError
(), udpsock
);  
   }
 
   memset(& SiTCPudpAddr
, 0, sizeof( SiTCPudpAddr
));  
    SiTCPudpAddr.sin_family      = AF_INET;
 
    SiTCPudpAddr.sin_port        = htons(udpPort);
 
    SiTCPudpAddr.sin_addr.s_addr = inet_addr(sitcpIpAddr);
 
   return 1;
 
 }
 
 //------------------------------------------------------------------------------------------------------ 
 
 int SiTCPCloseUDPSock(){
 
   printf("Close UDP Socket...");  
   closesocket(udpsock);
 
   return 1;
 
 }
 
 //------------------------------------------------------------------------------------------------------ 
 
 int SiTCPCloseTCPSock(){
 
   printf("Close TCP Socket...");  
   closesocket(tcpsock);
 
   return 1;
 
 }
 
 //------------------------------------------------------------------------------------------------------ 
 
 void SiTCPRBCPskeleton(unsigned char type, unsigned char command, unsigned char id,
 
                          unsigned char length, unsigned int address){
 
   SiTCPsndHeader.type=type;
 
   SiTCPsndHeader.command=command;
 
   SiTCPsndHeader.id=id;
 
   SiTCPsndHeader.length=length;
 
   SiTCPsndHeader.address=htonl(address);
 
   memcpy(SiTCPsndBuf
, &SiTCPsndHeader
, sizeof(SiTCPsndHeader
));  
}
 
//------------------------------------------------------------------------------------------------------ 
 
int SiTCPrcvRBCP_ACK(int output){
 
//printf("hogeeeee0");
 
  fd_set setSelect;
 
  int rcvdBytes;
 
  unsigned char rcvdBuf[1024];
 
  int rd_data;
 
 
 
  //  puts("\nWait to receive the ACK packet...");
 
 
 
  int recvVal = 1;
 
 
 
  while(recvVal){
 
//printf("hogeeeee1");
 
    FD_ZERO(&setSelect);
 
//printf("hogeeeee2");
 
    FD_SET(udpsock, &setSelect);
 
//printf("hogeeeee3");
 
    timeout.tv_sec  = 3;
 
    timeout.tv_usec = 0;
 
//printf("hogeeeee4");
 
    if(select(udpsock+1, &setSelect, NULL, NULL,&timeout)==0){
 
      // time out 
 
//printf("hogeeeee5");
 
      recvVal = 0;
 
      puts("\n***** Timeout ! *****");  
//printf("hogeeeee6");
 
      return -1;
 
    } 
 
    else {
 
      // receive packet 
 
//printf("hogeeeee7");
 
      if(FD_ISSET(udpsock,&setSelect)){
 
//printf("hogeeeee8");
 
        //rcvdBytes=recvfrom(udpsock, rcvdBuf, 2048, 0, NULL, NULL);
 
        rcvdBytes=recvfrom(udpsock, rcvdBuf, 1024, 0, NULL, NULL);
 
        if(rcvdBytes < 0) {
 
                Sleep(1000);
 
                rcvdBytes=recvfrom(udpsock, rcvdBuf, 1024, 0, NULL, NULL);
 
        }
 
//printf("hogeeee88");
 
        rcvdBuf[rcvdBytes]=0;
 
        if(output == 1){
 
          //puts("\n***** A pacekt is received ! *****.");
 
          //puts("Received data:");
 
//printf("hogeeeee9");
 
          int j=0;
 
          for(int i=0; i<rcvdBytes; i++){
 
            if(j==0) {
 
//printf("hogeeeee10");
 
              //printf("\t[%.3x]:%.2x ",i,rcvdBuf[i]);
 
              j++;
 
            }else if(j==3){
 
//printf("hogeeeee11");
 
              //printf("%.2x \n",rcvdBuf[i]);
 
              j=0;
 
            }else{
 
//printf("hogeeeee12");
 
              //printf("%.2x ",rcvdBuf[i]);
 
            j++;
 
            }
 
          }
 
          //puts("\n");
 
          rd_data = rcvdBuf[8];
 
        }
 
        recvVal = 0;
 
      }
 
    }
 
  }
 
  // printf("%.2x",rd_data);
 
  return rd_data;
 
  //usleep(50);  
 
}
 
//------------------------------------------------------------------------------------------------------ 
 
int SiTCPGetTCPSock(){return tcpsock;}
 
int SiTCPGetUDPSock(){return udpsock;} 
 
struct bcp_header SiTCPGetSiTCPsndHeader() {return SiTCPsndHeader;}