// socket library
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

// common declartions
#include "mc_send.h"
#include "declarations.h"

#define BUFSIZE   1024
#define TTL_VALUE 2
//#define TEST_ADDR "234.5.6.7"
//#define TEST_PORT 3456

//extern char *TEST_ADDR;
//extern int TEST_PORT;

#define LOOPMAX   10000

struct sockaddr_in stLocal, stTo, stFrom;
int s, i;
struct ip_mreq stMreq;
int iTmp, iRet;

void InitMCSocket()
{


  /* get a datagram socket */
  s = socket(AF_INET, 
     SOCK_DGRAM, 
     0);
  if (s == -1) {
    perror("socket() failed\n");
    exit(1);
  }

  /* avoid EADDRINUSE error on bind() */ 
  iTmp = 1;
  iRet = setsockopt(s, 
     SOL_SOCKET, 
     SO_REUSEADDR, 
     (char *)&iTmp, 
     sizeof(iTmp));
  if (iRet == -1) {
     perror("setsockopt1() failed\n");
  }

  /* name the socket */
  stLocal.sin_family = 	 AF_INET;
  stLocal.sin_addr.s_addr = htonl(INADDR_ANY);
  stLocal.sin_port = 	 htons(TEST_PORT);
  iRet = bind(s, (struct sockaddr*) &stLocal, sizeof(stLocal));
  if (iRet == -1) {
      perror("bind() failed\n");
  }

  /* join the multicast group. */
  stMreq.imr_multiaddr.s_addr = inet_addr(TEST_ADDR);
  stMreq.imr_interface.s_addr = INADDR_ANY;
  iRet = setsockopt(s, 
     IPPROTO_IP, 
     IP_ADD_MEMBERSHIP, 
     (char *)&stMreq, 
     sizeof(stMreq));
  if (iRet == -1) {
      perror("setsockopt2() failed\n");
  } 

  /* set TTL to traverse up to multiple routers */
  /*
  iTmp = TTL_VALUE;
  iRet = setsockopt(s, 
     IPPROTO_IP, 
     IP_MULTICAST_TTL, 
     (char *)&iTmp, 
     sizeof(iTmp));
  if (iRet == -1) {
      perror("setsockopt3() failed\n");
  }
  */
  /* disable loopback */
  /*
  iTmp = 0;
  iRet = setsockopt(s, 
     IPPROTO_IP, 
     IP_MULTICAST_LOOP, 
     (char *)&iTmp, 
     sizeof(iTmp));
  if (iRet == -1) {
      perror("setsockopt4() failed\n");
  }
  */
  /* assign our destination address */
  stTo.sin_family =      AF_INET;
  stTo.sin_addr.s_addr = inet_addr(TEST_ADDR);
  stTo.sin_port =        htons(TEST_PORT);
  #ifdef DEBUG_MCRECV
    printf ("jsalas Now sending to (and receiving from) multicast group: %s\n", TEST_ADDR);
  #endif  
}


// 030903
/*
void 
SendMC(Opt_M message) {
    int addr_size = sizeof(struct sockaddr_in);

    iRet = sendto(s,
      &message,
      sizeof(message),
      0,
      (struct sockaddr*)&stTo, 
      addr_size);
    if (iRet < 0) {
      perror("sendto() failed\n");
      exit(1);
    }

} 

void
RecvMC(Opt_M *message) {
    int addr_size = sizeof(struct sockaddr_in);
    static iCounter = 1;

 
    iRet = recvfrom(s, 
      message, 
      sizeof(Opt_M), 
      0,
      (struct sockaddr*)&stFrom, 
      &addr_size);
    if (iRet < 0) {
      perror("recvfrom() failed\n");
      exit(1);
    }
}
*/

void 
SendMC(T_Mess message) {
    int addr_size = sizeof(struct sockaddr_in);

    /* send to the multicast address */
    iRet = sendto(s,
      &message,
      sizeof(message),
      0,
      (struct sockaddr*)&stTo, 
      addr_size);
    if (iRet < 0) {
      perror("sendto() failed\n");
      exit(1);
    }

} 

void
RecvMC(T_Mess *message) {
    int addr_size = sizeof(struct sockaddr_in);
    static iCounter = 1;

    iRet = 0;

    iRet = recvfrom(s, 
      message, 
      sizeof(T_Mess), 
      0,
      (struct sockaddr*)&stFrom, 
      &addr_size);
   	if (iRet < 0) {
      perror("recvfrom() failed\n");
      exit(1);
    }
    /*
    printf("From host:%s port:%d, %d\n",
      inet_ntoa(stFrom.sin_addr), 
      ntohs(stFrom.sin_port), message->trans.tid);
    */
}

