/******************************************************************************/
/*                 Copyright C 1998-2002 Broadcom Corporation                 */
/*                                                                            */
/* This material is the confidential trade secret and proprietary information */
/* of Broadcom Corporation.  It may not be reproduced, used, sold or          */
/* transferred to any third party without the prior written consent of        */
/* Broadcom Corporation.   All rights reserved.                               */
/******************************************************************************/
/*   FileName        : bcm_genericOptions.c                                   */
/*   Purpose         : Provid a generic options parsing & usage startup       */
/*   Limitations     : None                                                   */
/*   Author          : Emmanuel Hanssens                                      */
/*   Creation Date   : 04-Jul-2002                                            */
/*   History         : Compiled by CVS                                        */
/******************************************************************************/
/*   $Id: bcm_genericOptions.c,v 1.25 2004/10/20 10:10:54 hanssens Exp $  */
/******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "bcm_genericOptions.h"
#include "bcm_userdef.h"
#ifndef _WIN32
# include <libgen.h>
#else
# define basename(name) name
#endif
#ifndef NO_HOST_ACCESS
# include "bcm_transfer.h"
#endif

/* {{{ Options strings and parameter global definitions */

char defUsage[80]="Usage: %s [list_of_options] \n";
int nbOfArguments = 0;

/* {{{ q option */
#ifndef UDP_PHY
char qOption[80]="\
   -q:         quick start, no booting (must be done elsewhere)\n";
int skipBoot = 0;
#endif
/* }}} */
/* {{{ R option */
#ifndef NO_HOST_ACCESS
char Roption[80]="\
   -R:         forces a reset (useful with -q option)\n";
int doReset  = 0;
#endif
/* }}} */
/* {{{ I option */
#ifndef NO_HOST_ACCESS
char Ioption[80]="\
   -I:         disable interrupt polling\n";
int dontPollInterrupt = 0;
#endif
/* }}} */
/* {{{ b option */
#if ! defined (NO_HOST_ACCESS) && ! defined (EEPROM_ON_BOARD)
char bOption[80]="\
   -b file:    file used as booter image (default: %s)\n";
char *booter_image_file   = "./broadcom_image/booter/boot_VE_4_0_1_tco.bin";
#endif
/* }}} */
/* {{{ t option */
#ifndef UDP_PHY
char tOption[80]="\
   -t file:    file used as target image (default: %s)\n";
char *firmware_image_file = "../../Binaries/modem/VE_6_2_4_tco.bin";
#endif
/* }}} */
#ifdef SOCKET_PHY
/* {{{ h option */
char hOption[80]="\
   -h host:    host running hmi proxy for socket PHY (default: %s)\n";
char *host_addr = "127.0.0.1"; /* localhost */
/* }}} */
/* {{{ p option */
char pOption[80]="\
   -p port:    ip port on host for socket PHY (default: %d)\n";
int host_port = 57665;
/* }}} */
#elif defined(UDP_PHY)
/* {{{ h option */
char hOption[80]="\
   -h devAddr: ip address of device (%d lines require %d -h options)\n";
/* }}} */
#elif defined(SERIAL_PHY)
/* {{{ s option */
char sOption[80]="\
   -s port:    serial port connected to EVM (default: %s)\n";
# ifdef SERIAL_PORT
char *serial_port = SERIAL_PORT;
# else
char *serial_port = "/dev/null";
# endif
/* }}} */
/* {{{ r option */
char rOption[80]="\
   -r rate:    baud rate for the serial port (default: %d)\n";
# ifdef SERIAL_SPEED
int serial_speed = SERIAL_SPEED;
# else
int serial_speed = 9600;
# endif
/* }}} */
/* {{{ d option */
char dOption[80]="\
   -d size:    data packet size used for serial transfer (default: %d)\n";
# ifdef PACKET_SIZE
int packet_size = PACKET_SIZE;
# else
int packet_size = 0;
# endif
/* }}} */
#elif defined(EP_PHY)
/* {{{ d option */
char dOption[80]="\
   -d dev:     device offset number (default: %d)\n";
/* }}} */
#endif
int device_offset = 0;          /* always defined to simplify code */
/* {{{ c option */
char cOption[80]="\
   -c port:    serial port used for test control (default: %s)\n";
/* test control port name */
#ifdef _WIN32
char *test_port         = "COM2";
#elif (PLATFORM == LINUX)
char *test_port         = "/dev/ttyS1";
#elif (PLATFORM == SOLARIS)
char *test_port         = "/dev/ttya";
#endif
/* }}} */
/* {{{ l option */
char lOption[80]="\
   -l line:    line to start (default: %d)\n";
char lOptionDef[80]="\
   -l line:    line to start (default: all %d lines)\n";
int   lineNumber = -1; /* means all lines per default */
/* }}} */
/* {{{ o option */
char oOption[80]="\
   -o port:    ip port on localhost for listening sockets (default: %d)\n";
int server_port = 57665;
/* }}} */
/* {{{ m option */
char  mOption[80]="\
   -m line:    enable data dump for specified line (into file DataDump.txt)\n";
int   dataDumpLineNumber  = -1; /* means data dump disabled */
/* }}} */

/* }}} */

/* {{{ Options parsing */

void GetOptions(int argc, char *argv[], char *reqOptions)
{
  int  strLen;
  int  c;
  char usage[1000];
  extern int optind, opterr;
  extern char *optarg;
#ifdef UDP_PHY
  int  nbIpAddr = 0;
  extern char *bcm6410ipAddr[];
#endif

  /* {{{ Build the default usage string */
  strLen = snprintf(usage, 1000, defUsage, basename(argv[0]));
  
  /* {{{ q option */

#ifndef UDP_PHY
  if (strchr(reqOptions, 'q') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, qOption);
#endif

  /* }}} */
  /* {{{ R option */

#ifndef NO_HOST_ACCESS
  if (strchr(reqOptions, 'R') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, Roption);
#endif

  /* }}} */
  /* {{{ I option */

#ifndef NO_HOST_ACCESS
  if (strchr(reqOptions, 'I') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, Ioption);
#endif

  /* }}} */
  /* {{{ b option */
  
#if ! defined (NO_HOST_ACCESS) && ! defined (EEPROM_ON_BOARD)
  if (strchr(reqOptions, 'b') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, bOption,
                       booter_image_file);
#endif

  /* }}} */
  /* {{{ t option */
  
#ifndef UDP_PHY
  if (strchr(reqOptions, 't') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, tOption,
                       firmware_image_file);
#endif

  /* }}} */
#ifdef SOCKET_PHY
  /* {{{ h option */

  if (strchr(reqOptions, 'h') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, hOption, host_addr);

  /* }}} */
  /* {{{ p option */

  if (strchr(reqOptions, 'p') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, pOption, host_port);

  /* }}} */
#elif defined(UDP_PHY)
  /* {{{ h option */

  if (strchr(reqOptions, 'h') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, hOption, NB_LINES,
                       NB_BCM_DEV);
  /* }}} */
#elif defined(SERIAL_PHY)
  /* {{{ s option */

  if (strchr(reqOptions, 's') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, sOption, serial_port);

  /* }}} */
  /* {{{ r option */

  if (strchr(reqOptions, 'r') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, rOption, serial_speed);

  /* }}} */
  /* {{{ d option */

  if (strchr(reqOptions, 'd') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, dOption, packet_size);

  /* }}} */
#elif defined(EP_PHY)
  /* {{{ d option */

  if (strchr(reqOptions, 'd') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, dOption, device_offset);

  /* }}} */
#endif
  /* {{{ o option */

  if (strchr(reqOptions, 'o') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, oOption, server_port);

  /* }}} */
  /* {{{ c option */

  if (strchr(reqOptions, 'c') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, cOption, test_port);

  /* }}} */
  /* {{{ l option */

  if (strchr(reqOptions, 'l') != NULL)
  {
    if (lineNumber == -1)
      strLen += snprintf(usage+strLen, 1000-strLen, lOptionDef, NB_LINES);
    else
      strLen += snprintf(usage+strLen, 1000-strLen, lOption, lineNumber);
  }

  /* }}} */
  /* {{{ m option */

  if (strchr(reqOptions, 'm') != NULL)
    strLen += snprintf(usage+strLen, 1000-strLen, mOption);

  /* }}} */
  /* }}} */

  /* {{{ parse the options */
  opterr = 0;                   /* avoid error in getopt */
  while ((c=getopt(argc, argv, reqOptions)) != -1)
    switch (c)
    {
        /* {{{ q option */
#ifndef UDP_PHY
      case 'q':
        skipBoot = 1;
        break;
#endif
        /* }}} */
        /* {{{ R option */
#ifndef NO_HOST_ACCESS
      case 'R':
        doReset = 1;
        break;
#endif
        /* }}} */
        /* {{{ I option */
#ifndef NO_HOST_ACCESS
      case 'I':
        dontPollInterrupt = 1;
        break;
#endif
        /* }}} */
        /* {{{ b option */
#if ! defined (NO_HOST_ACCESS) && ! defined (EEPROM_ON_BOARD)
      case 'b' :
        booter_image_file = strdup(optarg);
        break;
#endif
        /* }}} */
        /* {{{ t option */
#ifndef UDP_PHY
      case 't' :
        firmware_image_file = strdup(optarg);
        break;
#endif
        /* }}} */
#ifdef SOCKET_PHY
        /* {{{ h option */
      case 'h':
        /* special handling of -help option */
        if (! strcasecmp(optarg, "elp"))
        {
          printf(usage);
          exit(1);
        }
        host_addr = strdup(optarg);
        break;
        /* }}} */
        /* {{{ p option */
      case 'p':
        sscanf(optarg, "%d", &host_port);
        break;
        /* }}} */
#elif defined(UDP_PHY)
        /* {{{ h option */
      case 'h':
        /* special handling of -help option */
        if (! strcasecmp(optarg, "elp") || nbIpAddr == NB_BCM_DEV)
        {
          printf(usage);
          exit(1);
        }
        bcm6410ipAddr[nbIpAddr++] = strdup(optarg);
        break;
        /* }}} */
#elif defined(SERIAL_PHY)
        /* {{{ s option */
      case 's':
        serial_port = strdup(optarg);
        break;
        /* }}} */
        /* {{{ r option */
      case 'r':
        sscanf(optarg, "%d", &serial_speed);
        break;
        /* }}} */
        /* {{{ d option */
      case 'd':
        sscanf(optarg, "%d", &packet_size);
        break;
        /* }}} */
#elif defined(EP_PHY)
        /* {{{ d option */
      case 'd':
        sscanf(optarg, "%d", &device_offset);
        break;
        /* }}} */
#endif
        /* {{{ o option */
      case 'o':
        sscanf(optarg, "%d", &server_port);
        break;
        /* }}} */
        /* {{{ c option */
      case 'c':
        test_port = strdup(optarg);
        break;
        /* }}} */
        /* {{{ l option */
      case 'l' :
        sscanf(optarg, "%d", &lineNumber);
        break;
        /* }}} */
        /* {{{ m option */
      case 'm':
        sscanf(optarg, "%d", &dataDumpLineNumber);
        break;
        /* }}} */
      default :
        printf(usage);
        exit(1);
    }
  /* }}} */
  
#if defined(UDP_PHY)
  /* check whether we have all devices ip adresses */
  if (nbIpAddr != NB_BCM_DEV)
  {
    printf(usage);
    exit(1);
  }
#endif
  if ((argc-optind) != nbOfArguments)
  {
    printf(usage);
    exit(1);
  }
}
/* }}} */
