/* $header: /users/csgrads2/surendar/bigwpi/src/rcs/hybrid.c,v 1.5 1993/01/15 00:23:21 surendar exp surendar $ */

/*
 * module:	this module supports the hybrid layer functions.
 * author:	$author: surendar $ 
 * 		dept. of computer sciences 
 * 		worcester polytechnic institute. 
 * date:	$date: 1993/01/15 00:23:21 $ 
 */

/* 
 * $log: hybrid.c,v $
 * revision 1.5  1993/01/15  00:23:21  surendar
 * fixed prototypes
 *
 * revision 1.4  1993/01/15  00:20:50  surendar
 * dumps input data too for consistency
 *
 * revision 1.3  1993/01/15  00:17:37  surendar
 * oops, fixed my first bug
 *
 * revision 1.2  1993/01/14  19:07:36  surendar
 * checked in for assignment i
 * 
 */

#ifndef lint
static char rcs_ident[] = "$header: /users/csgrads2/surendar/bigwpi/src/rcs/hybrid.c,v 1.5 1993/01/15 00:23:21 surendar exp surendar $";
#endif /* lint */

#include	<stdio.h>
#include	<sys/types.h>
#include	<sys/time.h>
#include	<sys/param.h>
#include	<sys/socket.h>
#include	<sys/un.h>
#include	<sys/stat.h>
#include	<fcntl.h>

#if HAVE_STRING_H
#include	<string.h>
#endif /* HAVE_STRING_H */
#if HAVE_STDARG_H
#include	<stdarg.h>
#endif /* HAVE_STDARG_H */

#include	"defs.h"
#include	"extern.h"


/*
 * ====================================================================
 *
 * function: hl_process
 *
 * arguments: void
 *
 * return: void
 *
 * description: do all processing required in the hybrid layer
 *
 * ===================================================================
 */
void
    hl_process(void)
{
    int in_fid, out_fid;
    data_packet_t buf, *recv_buf;
    size_t len;
    err_t ret_value;
    int pkts_sent = 0, pkts_recv = 0;
    extern caddr_t shmcreate(size_t);
    ctrl_packet_t ctrl_buf, *ctrl_recv_buf;
    fd_set readfds;
    struct timeval timeout;
    char print_buf[132];
    
    log(10, "starting hybrid  layer");
    
    if (Server)
	{
	    while(phys_ptr->valid != 0x1010fefe) /* Rudimentary form of */
						 /* synchronization with */
						 /* the physical layer */
		{
		    FD_ZERO(&readfds); /* Ensure that we die if DL dies */
				       /* under us, because of some fatal */
				       /* error  */
		    FD_SET(aldl_fd, &readfds);
		    timeout.tv_sec = 0;
		    timeout.tv_usec = 0;
		    if (select(aldl_fd + 2, &readfds, NULL, NULL, &timeout)
			== 1)
			fatal("Protocol error");
		};
	    memcpy(&phys_control, phys_ptr, sizeof(phys_control));

	    log(20, phys_control.dest);
	    if ((out_fid = open(phys_control.dest,
				O_WRONLY | O_CREAT | O_TRUNC,
				0622)) < 0)
		fatal("Cannot open output file");

	    /* Something from data link layer?? */
	    while ((ret_value = dlhl_recv((void **) &recv_buf,
					  &len,
					  -1)) == Success)
		{
		    pkts_recv++;
		    if (recv_buf == NULL)
			log(0, "RECV buf is NULL");
		    
		    if (len == 0)
			log(0, "Length is 0");

		    dump("RECV", recv_buf, len);
		    switch(recv_buf->kind)
			{
			  case Data:
			    write(out_fid, recv_buf->buf, recv_buf->len);
			    free(recv_buf);
			    break;
			  case Ctrl:
			  case Stat:
			    log(0, recv_buf->buf);
			    break;
			  case Eof:
			    fatal("Transfer complete");
			    break;
			}
			    
		    ctrl_buf.kind = Stat;
		    sprintf(ctrl_buf.buf, "#%-d", pkts_recv);
		    if (hldl_send(&ctrl_buf, sizeof(ctrl_buf)) != Success)
			fatal("Data transmission failure");
		}
	}
    else
	{
	    if ((in_fid = open(source, O_RDONLY)) < 0)
		fatal("cannot open data file");
	    
	    memset(&buf, '\0', sizeof(buf));
	    while((buf.len = read(in_fid, buf.buf, sizeof(buf.buf))) > 0)
		{
		    dump("SEND", (void *) &buf, sizeof(buf));
		    /* Send to data link layer?? */
		    buf.kind = Data;
		    if (hldl_send(&buf, sizeof(buf)) != Success)
			fatal("Data transmission failure");
		    
		    pkts_sent++;
		    /* Something from data link layer?? */
		    if ((ret_value = dlhl_recv((void **) &ctrl_recv_buf, &len, 0)) == Success)
			{
			    pkts_sent--;
			    sprintf(print_buf,
				    "Packets transferred: %s",
				    ctrl_recv_buf->buf);
			    log(0, print_buf);
			    free(recv_buf);
			}
		    memset(&buf, '\0', sizeof(buf));
		}
	    
	    while(pkts_sent)		/* Hang around till all packets are */
		/* received back */
		if ((ret_value = dlhl_recv((void **) &ctrl_recv_buf, &len, 0)) == Success)
		    {
			pkts_sent--;
			sprintf(print_buf,
				"Packets transferred: %s",
				ctrl_recv_buf->buf);
			log(0, print_buf);
			free(recv_buf);
		    }
	    buf.kind = Eof;
	    if (hldl_send(&buf, sizeof(ctrl_packet_t)) != Success)
		fatal("Data transmission failure");
	}
	    
    close(in_fid);
    close(out_fid);
}
