/*

Copyright 1993, 1994, Cornell University

Cornell hereby grants permission to use, copy, modify, and distribute this program for any purpose 
and without fee, provided that these copyright and permission notices appear on all copies and 
supporting documentation, the name of Cornell not be used in advertising or publicity pertaining 
to distribution of the program without specific prior permission, notice be given in supporting 
documentation that copying and distribution is by permission of Cornell.  CORNELL MAKES NO 
REPRESENTATIONS OR WARRANTEES, EXPRESS OR IMPLIED.  By way of example, but not limitation, 
CORNELL MAKES NO REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR 
PURPOSE OR THAT THE USE OF THIS SOFTWARE OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, 
TRADEMARKS, OR OTHER RIGHTS.  Cornell shall not be held liable for any liability with respect to 
any claim by the user or any other party arising from use of the program.

This material is partially based on work sponsored by the National Science Foundation under Cooperative 
Agreement No. NCR-9318337.  The government has certain rights in this material.

*/



#include <stdio.h>
#include <signal.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>

#ifndef LINUX
#include <sys/socketvar.h>
#endif

#include <netinet/in.h>

#include "reflect.h"
#include "refmon.h"
#include "globals.h"

/* 
   initialize the list of servers from whom we hope to attain a stream of 
   Blind Carbon Copy video
*/

open_bcc_servers()
{
    VideoPacketHeader pkt;
    client *ctmp,ctmp1;
    short cnt,*id;

    for (cnt = 0; cnt < bcc_srv_cnt; cnt++)
    {
       pkt.routing.src.family = htons(kReflector);
       bcopy(&myaddr.sin_addr.s_addr,&pkt.routing.src.addr,4);
       pkt.routing.src.port = htons(VID_PORT);

       pkt.routing.dest.family = htons(kReflector);
       bcopy(&bcc_server_list[cnt],&pkt.routing.dest.addr,4);
       pkt.routing.dest.port = htons(VID_PORT);
   
       pkt.seqNum = 0;
       pkt.dataType = htons(kConfigRefType);
       pkt.len = htons(sizeof(VideoPacketHeader)+2);
       pkt.message = htons(kBCCOpen);
       id = (short *) ((char *) &pkt + HEADERLEN);
       *id = bcc_server_list_id[cnt];


#ifdef DEBUG
       if (debug)
          printf("sending BCC server keep alive ");
#endif

       /* 
          if the server is already in our client list. use its actual client
          ptr, else just us a temporary one for now
       */

       if ((ctmp = find_client(bcc_server_list[cnt])) == NULL)
       {
          bcopy(&bcc_server_list[cnt],&ctmp1.clnt_addr.addr,4);
          ctmp1.clnt_addr.family = AF_INET;
          ctmp1.clnt_addr.port = htons(VID_PORT);
          ctmp1.clnt_flags = BCC_SERVER;
          write_pkt(&pkt,&ctmp1);
       }
       else
          write_pkt(&pkt,ctmp);
    }
}

open_ucast_ref()
{
    VideoPacketHeader pkt;
    client *ctmp,ctmp1;
    short cnt;

    for (cnt = 0; cnt < ref_ucast_cnt; cnt++)
    {
       pkt.routing.src.family = htons(kReflector);
       bcopy(&myaddr.sin_addr.s_addr,&pkt.routing.src.addr,4);
       pkt.routing.src.port = htons(VID_PORT);

       pkt.routing.dest.family = htons(kReflector);
       bcopy(&bcc_server_list[cnt],&pkt.routing.dest.addr,4);
       pkt.routing.dest.port = htons(VID_PORT);
   
       pkt.seqNum = 0;
       pkt.dataType = htons(kConfigRefType);
       pkt.len = htons(sizeof(VideoPacketHeader));
       pkt.message =  htons(kREFOpen);


#ifdef DEBUG
       if (debug)
          printf("sending unicast server keep alive ");
#endif

       /* 
          if the server is already in our client list. use its actual client
          ptr, else just us a temporary one for now
       */

       if ((ctmp = find_client(ref_ucast_list[cnt])) == NULL)
       {
          bcopy(&ref_ucast_list[cnt],&ctmp1.clnt_addr.addr,4);
          ctmp1.clnt_addr.family = AF_INET;
          ctmp1.clnt_addr.port = htons(VID_PORT);
          ctmp1.clnt_flags = REF3_SERVER;
          write_pkt(&pkt,&ctmp1);
       }
       else
          write_pkt(&pkt,ctmp);
    }
}


rf_mcast_wrt(vidptr)
    VideoPacketHeader   *vidptr;

{
#ifdef DEBUG
       if (debug)
          printf("Multicasting (for RF) to %s\n",inet_ntoa(rfout_mcast.sin_addr));
#endif

    pkts_out++;
    bytes_out += ntohs(vidptr->len);

    if (sendto(rfout_mcast_sock,vidptr,ntohs(vidptr->len),0,&rfout_mcast,sizeof(struct sockaddr_in)) != ntohs(vidptr->len))
       dolog("mcast sendto error");

}

inout_mcast_wrt(vidptr)
    VideoPacketHeader   *vidptr;

{
#ifdef DEBUG
       if (debug)
          printf("Multicasting (to group) to %s\n",inet_ntoa(inout_mcast.sin_addr));
#endif

    pkts_out++;
    bytes_out += ntohs(vidptr->len);

    if (sendto(inout_mcast_sock,vidptr,ntohs(vidptr->len),0,&inout_mcast,sizeof(struct sockaddr_in)) != ntohs(vidptr->len))
       dolog("mcast sendto error");

}

