/*
 * Copyright 1988, 1989, 1990, 1991 Massachusetts Institute of Technology
 */
/* netrpd_driver.c: command routines for request forwarding */

#include "structs.h"
#include "netrpd.h"

typedef unsigned char byte;


/* ------------------------------------------------------------------------ */

netrpd_cmd(rpd,num)
     
     RPD_ptr	rpd;
     int 	num;
{
  int	res;
  int     state = 0, chan = 0;
  
  switch(num)
    {
    case INDEX_ON:
      chan = INDEX_CTRL;
      state = TURN_ON;
      rpd->state.indexon = 1;
    case INDEX_OFF:
      if (!chan) {
	chan = INDEX_CTRL;
	state = TURN_OFF;
	rpd->state.indexon = 0;
      }
    case INDEX_TOGGLE:
      if (!chan) {
	chan = INDEX_CTRL;
	if (rpd->state.indexon) {
	  state = TURN_OFF;
	  rpd->state.indexon = 0;
	}
	else {
	  state = TURN_ON;
	  rpd->state.indexon = 1;
	}
      }
    case A1_ON:
      if (!chan) {
	chan = LEFT_CHAN;
	state = TURN_ON;
      }
    case A1_OFF:
      if (!chan) {
	chan = LEFT_CHAN;
	state = TURN_OFF;
      }
    case SQUELCH_ON:
      if (!chan) {
	chan = SQUELCH_CTRL;
	state = TURN_ON;
      }
    case SQUELCH_OFF:
      if (!chan) {
	chan = SQUELCH_CTRL;
	state = TURN_OFF;
      }
    case A2_ON:
      if (!chan) {
	chan = RIGHT_CHAN;
	state = TURN_ON;
      }
    case A2_OFF:
      if (!chan) {
	chan = RIGHT_CHAN;
	state = TURN_OFF;
      }
      if (add_lock(rpd->serv) == -1) return(-1);
      res=GConfigure(rpd->serv,rpd->volnum,chan,state);
      if (res == GIO_ERROR) {
	bsdsyslog(LOG_NOTICE,
		  "netrpd_cmd: GIO_ERROR: %s",rpd->devname);
	need_to_rebuild_list = 1;
	return(-1);
      }
      if (sync_mode == SYNC_MODE) {
	res = GRelease(rpd->serv);
	if (res == GIO_ERROR) {
	  bsdsyslog(LOG_NOTICE,
		    "netrpd_cmd: GIO_ERROR: %s",rpd->devname);
	  need_to_rebuild_list = 1;
	  return(-1);
	}
      }
      break;
    case FORKLOAD:
      return(-1);
      break;
    case STARTLOAD:
    case ENDLOAD:
    case LOAD:
      rpd_setframe (rpd, -1);  /* this always forces getframe, etc... */
      break;
    case EJECT:
    case UNLOAD:
      break;
    default:
      bsdsyslog(LOG_NOTICE,"netrpd_cmd: illegal request %d\n",num);
      break;
    }
  return(0);
}

/* ------------------------------------------------------------------------ */

netrpd_varspeed(rpd,num)
     
     RPD_ptr	rpd;
     int	num;
{
  int	res;
  int     len;
  
  if (add_lock(rpd->serv) == -1) return(-1);
  res = GRun(rpd->serv,rpd->volnum,num,0);
  if (res == GIO_ERROR) {
    bsdsyslog(LOG_NOTICE,
	      "netrpd_varspeed: GIO_ERROR: %s",rpd->devname);
    need_to_rebuild_list = 1;
    return(-1);
  }
  if (sync_mode == SYNC_MODE) {
    len = GRelease(rpd->serv);
    if (len == GIO_ERROR) {
      bsdsyslog(LOG_NOTICE,
		"netrpd_varspeed: GIO_ERROR: %s",rpd->devname);
      need_to_rebuild_list =1;
      return(-1);
    }
  }
  return(res);
}

/* ------------------------------------------------------------------------ */

netrpd_jog(rpd,num)
     
     RPD_ptr	rpd;
     int	num;
{
  int	dir;
  int     res;
  
  if (add_lock(rpd->serv) == -1) return(-1);
  res = GJog(rpd->serv,rpd->volnum,num,0);
  if (res == GIO_ERROR) {
    bsdsyslog(LOG_NOTICE,
	      "netrpd_jog: GIO_ERROR: %s",rpd->devname);
    need_to_rebuild_list = 1;
    return(-1);
  }
  if (sync_mode == SYNC_MODE) {
    dir = GRelease(rpd->serv);
    if (dir == GIO_ERROR) {
      bsdsyslog(LOG_NOTICE,
		"netrpd_jog: GIO_ERROR: %s",rpd->devname);
      need_to_rebuild_list = 1;
      return(-1);
    }
  }
  return (res);
}

/* ------------------------------------------------------------------------ */

netrpd_getframe(rpd)
     
     RPD_ptr	rpd;
{
  int	res;
  int     dir;
  
  if (add_lock(rpd->serv) == -1) return(-1);
  res = GGetFrame(rpd->serv,rpd->volnum);
  if (res == GIO_ERROR) {
    bsdsyslog(LOG_NOTICE,
	      "netrpd_getframe: GIO_ERROR: %s",rpd->devname);
    need_to_rebuild_list = 1;
    return(-1);
  }
  if (sync_mode == SYNC_MODE) {
    dir = GRelease(rpd->serv);
    if (dir == GIO_ERROR) {
      bsdsyslog(LOG_NOTICE,
		"netrpd_getframe: GIO_ERROR: %s",rpd->devname);
      need_to_rebuild_list = 1;
      return(-1);
    }
  }
  return (res);
}

/* ------------------------------------------------------------------------ */

netrpd_getspeed(rpd)
     
     RPD_ptr	rpd;
{
  int	res;
  int     dir;
  
  if (add_lock(rpd->serv) == -1) return(-1);
  res = GGetSpeed(rpd->serv,rpd->volnum);
  if (res == GIO_ERROR) {
    bsdsyslog(LOG_NOTICE,
	      "netrpd_getspeed: GIO_ERROR: %s",rpd->devname);
    need_to_rebuild_list = 1;
    return(-1);
  }
  if (sync_mode == SYNC_MODE) {
    dir = GRelease(rpd->serv);
    if (dir == GIO_ERROR) {
      bsdsyslog(LOG_NOTICE,
		"netrpd_getspeed: GIO_ERROR: %s",rpd->devname);
      need_to_rebuild_list = 1;
      return(-1);
    }
  }
  return (res);
}


/* ------------------------------------------------------------------------ */
/*ARGSUSED*/
netrpd_search(rpd,frame,wait)
     
     RPD_ptr	rpd;
     int	frame;
     int	wait;		/* if true, hangs until it gets there 
				   or times out */
{
  int	res;
  int     dir;
  int save_sync;

  if (add_lock(rpd->serv) == -1) return(-1);
  save_sync = sync_mode;
  if (wait == 0) {
    sync_mode = ASYNC_MODE;
    GSetState(0,0,sync_mode);
  }
  res = GSearch(rpd->serv,rpd->volnum,frame,0);
  if (res == GIO_ERROR) {
    bsdsyslog(LOG_NOTICE,
	      "netrpd_search: GIO_ERROR: %s",rpd->devname);
    need_to_rebuild_list = 1;
    sync_mode = save_sync;
    GSetState(0,0,sync_mode);
    return(-1);
  }	  
  if (sync_mode == SYNC_MODE) {
    dir = GRelease(rpd->serv);
    if (dir == GIO_ERROR) {
      bsdsyslog(LOG_NOTICE,
		"netrpd_search: GIO_ERROR: %s",rpd->devname);
      need_to_rebuild_list = 1;
      sync_mode = save_sync;
      GSetState(0,0,sync_mode);
      return(-1);
    }
  }
  sync_mode = save_sync;
  GSetState(0,0,sync_mode);
  if (res != frame) return(-1);
  else return(0);
}
/* ------------------------------------------------------------------------ */

netrpd_reset(rpd)
     
     RPD_ptr	rpd;
{
  
  int	ret = 0;
  int     dir;
  
  return 0;
#ifdef OBSOLETE    
  if (add_lock(rpd->serv)== -1) return(-1); 
  dir = GReset(rpd->serv,rpd->volnum);
  if (dir == GIO_ERROR) {
    bsdsyslog(LOG_NOTICE,
	      "netrpd_reset: GIO_ERROR: %s",rpd->devname);
    need_to_rebuild_list = 1;
    return(-1);
  }
  if (sync_mode == SYNC_MODE) {
    dir = GRelease(rpd->serv);
    if (dir == GIO_ERROR) {
      bsdsyslog(LOG_NOTICE,
		"netrpd_reset: GIO_ERROR: %s",rpd->devname);
      need_to_rebuild_list = 1;
      return(-1);
    }
  }
  return ret;
#endif /* OBSOLETE */
}

/* ------------------------------------------------------------------------ */

netrpd_segplay(rpd,f1,f2,speed,wait)
     
     RPD_ptr	rpd;
     int	f1,f2;
     int     speed;
     int	wait;		/* if true, hangs until done */
{
  int  res;
  
  if (add_lock(rpd->serv) == -1) return(-1);  
  res = GPlaySeg(rpd->serv,rpd->volnum,f1,f2,speed,0,wait);
  if (res == GIO_ERROR) {
    bsdsyslog(LOG_NOTICE,
	      "netrpd_segplay: GIO_ERROR: %s",rpd->devname);
    need_to_rebuild_list = 1;
    return(-1);
  }
  if (sync_mode == SYNC_MODE) {
    res = GRelease(rpd->serv);
    if (res == GIO_ERROR) {
      bsdsyslog(LOG_NOTICE,
		"netrpd_segplay: GIO_ERROR: %s",rpd->devname);
      need_to_rebuild_list = 1;
      return(-1);
    }
  }
  return(0);
}

/* ------------------------------------------------------------------------ */

netrpd_record(rpd)
     RPD_ptr rpd;
{
  bsdsyslog(LOG_NOTICE, "netrpd_record: %s: should never be executed!!",
	    rpd->devname);
  return -1;
}

/* ------------------------------------------------------------------------ */

netrpd_proddev(rpd)
     RPD_ptr rpd;
{
  return 0;
}

/* ------------------------------------------------------------------------ */

netrpd_setfuncs( disc )
     
     RPD_ptr	disc;
{
  disc->proddev = netrpd_proddev;
  disc->reset = netrpd_reset;
  disc->cmd = netrpd_cmd;
  disc->search = netrpd_search;
  disc->segplay = netrpd_segplay;
  disc->getframe = netrpd_getframe;
  disc->getspeed = netrpd_getspeed;
  disc->varspeed = netrpd_varspeed;
  disc->jog = netrpd_jog;
  if (disc->devtype == NETRPD_RECORD)
    disc->record = netrpd_record;
  else
    disc->record = NULL;
  disc->lastframe = 999999;
}
