/* *********************************************************
 * *                                                       *
 * *      Process Deletion for IRIS antenna driver         *
 * *                                                       *
 * *********************************************************
 * File: utils/antenna/qant.C
 *
 *         COPYRIGHT (c) 1994, 1996, 1999, 2002, 2003, 2004 BY
 *         SIGMET INCORPORATED, WESTFORD MASSACHUSETTS, U.S.A.
 *
 * THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND  COPIED
 * ONLY  IN  ACCORDANCE WITH  THE  TERMS  OF  SUCH  LICENSE  AND WITH THE
 * INCLUSION OF THE ABOVE COPYRIGHT NOTICE.  THIS SOFTWARE  OR  ANY OTHER
 * COPIES  THEREOF MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY
 * OTHER PERSON.  NO TITLE TO AND OWNERSHIP OF  THE  SOFTWARE  IS  HEREBY
 * TRANSFERED.
 */
#include <errno.h>
#include <locale.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>

#include "sigtypes.h"
#include "user_lib.h"
#include "antenna_lib.h"
#include "antenna_int.h"

static UINT2 ant_shmem_inuse( UINT2 lprint_a );

/* ======================================================================
 * Kill all processes with names that start with "IRIS_ANT".  This
 * will shut down the antenna driver.
 * History:
 *     jmh   21 Jan 1994   Copied from qiris
 */
int main( int argc_a, char** argv_a )
{
  MESSAGE istatus ;
  UINT2 lcreated ; SINT4 ii ;
  UINT4 iant_rcv_pid[2], iant_xmt_pid[2], iLogPID ;
  UINT4 isim_rcv_pid   , isim_xmt_pid    ;

  setlocale( LC_ALL, "" );

  /* Open both global sections to get process IDs
   */
  istatus = AntPowerUpMain( ANT_IAM_QANT, 0 );
  if( istatus == SS_NORMAL ) {
    antWriteLog( "Shutting down the antenna driver" ) ;
    ant_get_pids( iant_rcv_pid, iant_xmt_pid, &iLogPID ) ;
  } else {
    sig_signal( istatus ) ;
    iant_rcv_pid[0] = 0 ; iant_rcv_pid[1] = 0 ;
    iant_xmt_pid[0] = 0 ; iant_xmt_pid[1] = 0 ;
    iLogPID         = 0 ;
  }
  istatus = antsim_global_init( &lcreated );
  if (istatus == SS_NORMAL) {
    antsim_get_pids( &isim_rcv_pid, &isim_xmt_pid ) ;
  } else {
    sig_signal( istatus );
    isim_rcv_pid = 0 ; isim_xmt_pid = 0 ;
  }

  /* Proceed with removing all the processes.
   */
  if ( iant_rcv_pid[0] )
    {
      printf("Deleting ANT_RCV, PID=%d.\n", iant_rcv_pid[0] );
      if( kill( (pid_t)iant_rcv_pid[0], SIGTERM ) == -1 )
	sig_signal( errno_to_message( errno ) ) ;
    }

  if ( iant_xmt_pid[0] )
    {
      printf("Deleting ANT_XMT, PID=%d.\n", iant_xmt_pid[0] );
      if( kill( (pid_t)iant_xmt_pid[0], SIGTERM ) == -1 )
	sig_signal( errno_to_message( errno ) ) ;
    }

  if ( iant_rcv_pid[1] )
    {
      printf("Deleting ANT_RCV2, PID=%d.\n", iant_rcv_pid[1] );
      if( kill( (pid_t)iant_rcv_pid[1], SIGTERM ) == -1 )
	sig_signal( errno_to_message( errno ) ) ;
    }

  if ( iant_xmt_pid[1] )
    {
      printf("Deleting ANT_XMT2, PID=%d.\n", iant_xmt_pid[1] );
      if( kill( (pid_t)iant_xmt_pid[1], SIGTERM ) == -1 )
	sig_signal( errno_to_message( errno ) ) ;
    }

  if ( isim_rcv_pid )
    {
      printf("Deleting ANTSIM_RCV, PID=%d.\n", isim_rcv_pid );
      if( kill( (pid_t)isim_rcv_pid, SIGTERM ) == -1 )
	sig_signal( errno_to_message( errno ) ) ;
    }

  if ( isim_xmt_pid )
    {
      printf("Deleting ANTSIM_XMT, PID=%d.\n", isim_xmt_pid );
      if( kill( (pid_t)isim_xmt_pid, SIGTERM ) == -1 )
	sig_signal( errno_to_message( errno ) ) ;
    }

  /* Sleep a little while to allow other programs to shutdown and for
   * final logs to be written, then kill the logging process and sleep
   * a little more for it to exit cleanly.
   */
  sig_microSleep( 250000 ) ;
  if( iLogPID ) {
    printf("Deleting ANT_LOG, PID=%d.\n", iLogPID );
    if( kill( (pid_t)iLogPID, SIGTERM ) == -1 )
      sig_signal( errno_to_message( errno ) ) ;
  }
  sig_microSleep( 250000 ) ;

  /* Close the driver after killing all subprocesses (so they don't
   * get errors when semaphores are removed).
   */
  istatus = ant_close();
  if (istatus != SS_NORMAL) sig_signal( istatus );
  istatus = antsim_close() ;
  if (istatus != SS_NORMAL) sig_signal( istatus ) ;

  /* Verify that the shared segments seem to have gone away
   */
  for( ii=0 ;; ii++ ) {
    if( 0 == ant_shmem_inuse(0) ) { if( ii > 1 ) printf( "\n" ) ; break ; }
    if( ii == 1 ) { printf( "\nWaiting for release of shared memory" ) ; fflush(0) ; }
    if( ii > 0 ) { printf( "." ) ; fflush(0) ; } sig_microSleep(1000000) ;
    if( ii >= 10 ) { printf( "\n" ) ; ant_shmem_inuse(1) ; break ; }
  }

  exit(EXIT_SUCCESS) ;
}

/* ======================================================================
 * Check whether any shared memory segments are still in use, and remove
 * them by doing a final detach.
 */
static UINT2 ant_shmem_inuse( UINT2 lprint_a ) {
  UINT4 inuse=FALSE ;
  if( lshmem_inuse( "iris_antenna", lprint_a ) ) inuse=TRUE ;
  if( lshmem_inuse( "iris_antsim" , lprint_a ) ) inuse=TRUE ;
  return( inuse ) ;
}
