/* Copyright (c) 1991-2002 Doshita Lab. Speech Group, Kyoto University */
/* Copyright (c) 2000-2002 Speech and Acoustics Processing Lab., NAIST */
/*   All rights reserved   */

/* adin_tcpip.c --- adin via TCP/IP network */

/* $Id: adin_tcpip.c,v 1.4 2002/12/02 06:02:25 ri Exp $ */

/* ignore sampling frequency config. ... incoming speech stream via socket is undoubtedly accepted without qualification.  Be care! */

#include <sent/stddefs.h>
#include <sent/adin.h>
#include <sent/tcpip.h>
#include <poll.h>

static int adinnet_sd = -1; /* socket for adinserv */
static int adinnet_asd = -1; /* socket for adinserv */
static boolean last_is_segmented = FALSE; /* FALSE if last is end of connection */

static pid_t child;		/* child process ID (0 if myself is child) */
/* setup device */
boolean
adin_tcpip_standby(int freq, void *port_str)
{
  int port;

  port = atoi((char *)port_str);

  /* currently frequency is ommited */
  if ((adinnet_sd = ready_as_server(port)) < 0) {
    j_printerr("adin_tcpip_standby: cannot ready for server\n");
    return FALSE;
  }

  last_is_segmented = FALSE;
}

boolean
adin_tcpip_begin()
{
  if (last_is_segmented) {
    /* just wait for the next segment to be received */
  } else {
    /***********************************/
    /*** server infinite loop here!! ***/
    /***********************************/
    for (;;) {
      /* wait connection */
      j_printerr("waiting connection...\n");
      adinnet_asd = accept_from(adinnet_sd);
      /* fork self */
      child = fork();
      if (child < 0) {		/* error */
	j_printerr("adin_tcpip_standby: fork failed\n");
	return FALSE;
      }
      /* child thread should handle this request */
      if (child == 0) {		/* child thread */
	break;			/* proceed */
      } else {			/* parent thread */
	j_printerr("forked process [%d] handles this request\n", child);
      }
    }
  }
  return TRUE;
}

/* resume recording */
boolean
adin_tcpip_end()
{
  if (!last_is_segmented) {
    /* end of connection: exit this process */
    close(adinnet_asd);
    j_error("connection end\n");
  } /* else, end of segment: wait for next input in current socket */
}

/* try to read `sampnum' samples and returns actual sample num recorded */
int
adin_tcpip_read(SP16 *buf, int sampnum)
{
  int cnt, ret;
  struct pollfd p;
  int status;
  
  /* check if some commands are waiting in queue */
  p.fd = adinnet_asd;
  p.events = POLLIN;
  status = poll(&p, 1, 50);
  if (status < 0) {
    j_printerr("adin_tcpip_read: cannot poll\n");
    return -2;			/* error */
  }
  if (status > 0) {		/* there are some data */
    ret = rd(adinnet_asd, (char *)buf, &cnt, sampnum * sizeof(SP16));
    if (ret == 0) {
      /* end of segment mark */
      last_is_segmented = TRUE;
      return -1;
    }
    if (ret < 0) {
      /* end of input, mark */
      last_is_segmented = FALSE;
      return -1;
    }
  } else {
    cnt = 0;			/* no data */
  }
  cnt /= sizeof(SP16);
  return cnt;
}
