/* 
 * Copyright (C) 1995 Advanced RISC Machines Limited. All rights reserved.
 * 
 * This software may be freely used, copied, modified, and distributed
 * provided that the above copyright notice is preserved in all copies of the
 * software.
 */

/* -*-C-*-
 *
 * $Revision$
 *     $Date$
 *
 *
 * serdrv.c - Synchronous Serial Driver for Angel.
 *            This is nice and simple just to get something going.
 */

#ifdef __hpux
#  define _POSIX_SOURCE 1
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "crc.h"
#include "devices.h"
#include "buffers.h"
#include "rxtx.h"
#include "hostchan.h"
#include "params.h"
#include "logging.h"

extern int baud_rate;   /* From gdb/top.c */

#ifdef COMPILING_ON_WINDOWS
#  undef   ERROR
#  undef   IGNORE
#  include <windows.h>
#  include "angeldll.h"
#  include "comb_api.h"
#else
#  ifdef __hpux
#    define _TERMIOS_INCLUDED
#    include <sys/termio.h>
#    undef _TERMIOS_INCLUDED
#  else
#    include <termios.h>
#  endif
#  include "unixcomm.h"
#endif

#ifndef UNUSED
#  define UNUSED(x) (x = x)      /* Silence compiler warnings */
#endif
 
#define MAXREADSIZE 512
#define MAXWRITESIZE 512

#define SERIAL_FC_SET  ((1<<serial_XON)|(1<<serial_XOFF))
#define SERIAL_CTL_SET ((1<<serial_STX)|(1<<serial_ETX)|(1<<serial_ESC))
#define SERIAL_ESC_SET (SERIAL_FC_SET|SERIAL_CTL_SET)

static const struct re_config config = {
    serial_STX, serial_ETX, serial_ESC, /* self-explanatory?               */
    SERIAL_FC_SET,                      /* set of flow-control characters  */
    SERIAL_ESC_SET,                     /* set of characters to be escaped */
    NULL /* serial_flow_control */, NULL  ,    /* what to do with FC chars */
    angel_DD_RxEng_BufferAlloc, NULL                /* how to get a buffer */
};

static struct re_state rxstate;

typedef struct writestate {
  unsigned int wbindex;
  /*  static te_status testatus;*/
  unsigned char writebuf[MAXWRITESIZE];
  struct te_state txstate;
} writestate;

static struct writestate wstate;

/*
 * The set of parameter options supported by the device
 */
static unsigned int baud_options[] = {
#if defined(B115200) || defined(__hpux)
    115200,
#endif
#if defined(B57600) || defined(__hpux)
    57600, 
#endif
    38400, 19200, 9600
};

static ParameterList param_list[] = {
    { AP_BAUD_RATE,
      sizeof(baud_options)/sizeof(unsigned int),
      baud_options }
};

static const ParameterOptions serial_options = {
    sizeof(param_list)/sizeof(ParameterList), param_list };

/* 
 * The default parameter config for the device
 */
static Parameter param_default[] = {
    { AP_BAUD_RATE, 9600 }
};

static ParameterConfig serial_defaults = {
    sizeof(param_default)/sizeof(Parameter), param_default };

/*
 * The user-modified options for the device
 */
static unsigned int user_baud_options[sizeof(baud_options)/sizeof(unsigned)];

static ParameterList param_user_list[] = {
    { AP_BAUD_RATE,
      sizeof(user_baud_options)/sizeof(unsigned),
      user_baud_options }
};

static ParameterOptions user_options = {
    sizeof(param_user_list)/sizeof(ParameterList), param_user_list };

static bool user_options_set;

/* forward declarations */
static int serial_reset( void );
static int serial_set_params( const ParameterConfig *config );
static int SerialMatch(const char *name, const char *arg);

static void process_baud_rate( unsigned int target_baud_rate )
{
    const ParameterList *full_list;
    ParameterList       *user_list;

    /* create subset of full options */
    full_list = Angel_FindParamList( &serial_options, AP_BAUD_RATE );
    user_list = Angel_FindParamList( &user_options,   AP_BAUD_RATE );

    if ( full_list != NULL && user_list != NULL )
    {
        unsigned int i, j;
        unsigned int def_baud = 0;

        /* find lower or equal to */
        for ( i = 0; i < full_list->num_options; ++i )
           if ( target_baud_rate >= full_list->option[i] )
           {
               /* copy remaining */
               for ( j = 0; j < (full_list->num_options - i); ++j )
                  user_list->option[j] = full_list->option[i+j];
               user_list->num_options = j;

               /* check this is not the default */
               Angel_FindParam( AP_BAUD_RATE, &serial_defaults, &def_baud );
               if ( (j == 1) && (user_list->option[0] == def_baud) )
               {
#ifdef DEBUG
                   printf( "user selected default\n" );
#endif
               }
               else
               {
                   user_options_set = TRUE;
#ifdef DEBUG
                   printf( "user options are: " );
                   for ( j = 0; j < user_list->num_options; ++j )
                      printf( "%u ", user_list->option[j] );
                   printf( "\n" );
#endif
               }

               break;   /* out of i loop */
           }
                
#ifdef DEBUG
        if ( i >= full_list->num_options )
           printf( "couldn't match baud rate %u\n", target_baud_rate );
#endif
    }
#ifdef DEBUG
    else
       printf( "failed to find lists\n" );
#endif
}

static int SerialOpen(const char *name, const char *arg)
{
    const char *port_name = name;

#ifdef DEBUG
    printf("SerialOpen: name %s arg %s\n", name, arg ? arg : "<NULL>");
#endif

#ifdef COMPILING_ON_WINDOWS
    if (IsOpenSerial()) return -1;
#else
    if (Unix_IsSerialInUse()) return -1;
#endif

#ifdef COMPILING_ON_WINDOWS
    if (SerialMatch(name, arg) != adp_ok)
        return adp_failed;
#else
    port_name = Unix_MatchValidSerialDevice(port_name);
# ifdef DEBUG
    printf("translated port to %s\n", port_name == 0 ? "NULL" : port_name);
# endif
    if (port_name == 0) return adp_failed;
#endif

    user_options_set = FALSE;

    /* interpret and store the arguments */
    if ( arg != NULL )
    {
        unsigned int target_baud_rate;
        target_baud_rate = (unsigned int)strtoul(arg, NULL, 10);
        if (target_baud_rate > 0)
        {
#ifdef DEBUG
            printf( "user selected baud rate %u\n", target_baud_rate );
#endif
            process_baud_rate( target_baud_rate );
        }
#ifdef DEBUG
        else
           printf( "could not understand baud rate %s\n", arg );
#endif
    }
    else if (baud_rate > 0)
    {
      /* If the user specified a baud rate on the command line "-b" or via
         the "set remotebaud" command then try to use that one */
      process_baud_rate( baud_rate );
    }

#ifdef COMPILING_ON_WINDOWS
    {
        int port = IsValidDevice(name);
        if (OpenSerial(port, FALSE) != COM_OK)
            return -1;
    }
#else
    if (Unix_OpenSerial(port_name) < 0)
      return -1;
#endif

    serial_reset();

#if defined(__unix) || defined(__CYGWIN__)
    Unix_ioctlNonBlocking();
#endif

    Angel_RxEngineInit(&config, &rxstate);
    /*
     * DANGER!: passing in NULL as the packet is ok for now as it is just
     * IGNOREd but this may well change
     */
    Angel_TxEngineInit(&config, NULL, &wstate.txstate); 
    return 0;
}

static int SerialMatch(const char *name, const char *arg)
{
    UNUSED(arg);
#ifdef COMPILING_ON_WINDOWS
    if (IsValidDevice(name) == COM_DEVICENOTVALID)
        return -1;
    else
        return 0;
#else
    return Unix_MatchValidSerialDevice(name) == 0 ? -1 : 0;
#endif
}

static void SerialClose(void)
{
#ifdef DO_TRACE
    printf("SerialClose()\n");
#endif

#ifdef COMPILING_ON_WINDOWS
    CloseSerial();
#else
    Unix_CloseSerial();
#endif
}

static int SerialRead(DriverCall *dc, bool block) {
  static unsigned char readbuf[MAXREADSIZE];
  static int rbindex=0;

  int nread;
  int read_errno;
  int c=0;
  re_status restatus;
  int ret_code = -1;            /* assume bad packet or error */

  /* must not overflow buffer and must start after the existing data */
#ifdef COMPILING_ON_WINDOWS
  {
    BOOL dummy = FALSE;
    nread = BytesInRXBufferSerial();

    if (nread > MAXREADSIZE - rbindex)
      nread = MAXREADSIZE - rbindex;

    if ((read_errno = ReadSerial(readbuf+rbindex, nread, &dummy)) == COM_READFAIL)
    {
        MessageBox(GetFocus(), "Read error\n", "Angel", MB_OK | MB_ICONSTOP);
        return -1;   /* SJ - This really needs to return a value, which is picked up in */
                     /*      DevSW_Read as meaning stop debugger but don't kill. */
    }
    else if (pfnProgressCallback != NULL && read_errno == COM_OK)
    {
      progressInfo.nRead += nread;
      (*pfnProgressCallback)(&progressInfo);
    }
  }
#else
  nread = Unix_ReadSerial(readbuf+rbindex, MAXREADSIZE-rbindex, block);
  read_errno = errno;
#endif

  if ((nread > 0) || (rbindex > 0)) {

#ifdef DO_TRACE
    printf("[%d@%d] ", nread, rbindex);
#endif

    if (nread>0)
       rbindex = rbindex+nread;

    do {
      restatus = Angel_RxEngine(readbuf[c], &(dc->dc_packet), &rxstate);
#ifdef DO_TRACE
      printf("<%02X ",readbuf[c]);
      if (!(++c % 16))
          printf("\n");
#else
      c++;
#endif
    } while (c<rbindex &&
             ((restatus == RS_IN_PKT) || (restatus == RS_WAIT_PKT)));

#ifdef DO_TRACE
   if (c % 16)
        printf("\n");
#endif

    switch(restatus) {
      
      case RS_GOOD_PKT:
        ret_code = 1;
        /* fall through to: */

      case RS_BAD_PKT:
        /*
         * We now need to shuffle any left over data down to the
         * beginning of our private buffer ready to be used 
         *for the next packet 
         */
#ifdef DO_TRACE
        printf("SerialRead() processed %d, moving down %d\n", c, rbindex-c);
#endif
        if (c != rbindex) memmove((char *) readbuf, (char *) (readbuf+c),
                                  rbindex-c);
        rbindex -= c;
        break;

      case RS_IN_PKT:
      case RS_WAIT_PKT:
        rbindex = 0;            /* will have processed all we had */
        ret_code = 0;
        break;

      default:
#ifdef DEBUG
        printf("Bad re_status in serialRead()\n");
#endif
        break;
    }
  } else if (nread == 0)
    ret_code = 0;               /* nothing to read */
  else if (read_errno == ERRNO_FOR_BLOCKED_IO) /* nread < 0 */
    ret_code = 0;

#ifdef DEBUG
  if ((nread<0) && (read_errno!=ERRNO_FOR_BLOCKED_IO))
    perror("read() error in serialRead()");
#endif

  return ret_code;
}


static int SerialWrite(DriverCall *dc) {
  int nwritten = 0;
  te_status testatus = TS_IN_PKT;

  if (dc->dc_context == NULL) {
    Angel_TxEngineInit(&config, &(dc->dc_packet), &(wstate.txstate));
    wstate.wbindex = 0;
    dc->dc_context = &wstate;
  }

  while ((testatus == TS_IN_PKT) && (wstate.wbindex < MAXWRITESIZE))
  {
    /* send the raw data through the tx engine to escape and encapsulate */
    testatus = Angel_TxEngine(&(dc->dc_packet), &(wstate.txstate),
                              &(wstate.writebuf)[wstate.wbindex]);
    if (testatus != TS_IDLE) wstate.wbindex++;
  }

  if (testatus == TS_IDLE) {
#ifdef DEBUG
    printf("SerialWrite: testatus is TS_IDLE during preprocessing\n");
#endif
  }

#ifdef DO_TRACE
  { 
    int i = 0;

    while (i<wstate.wbindex)
    {
        printf(">%02X ",wstate.writebuf[i]);

        if (!(++i % 16))
            printf("\n");
    }
    if (i % 16)
        printf("\n");
  }
#endif

#ifdef COMPILING_ON_WINDOWS
  if (WriteSerial(wstate.writebuf, wstate.wbindex) == COM_OK)
  {
    nwritten = wstate.wbindex;
    if (pfnProgressCallback != NULL)
    {
      progressInfo.nWritten += nwritten;
      (*pfnProgressCallback)(&progressInfo);
    }
  }
  else
  {
      MessageBox(GetFocus(), "Write error\n", "Angel", MB_OK | MB_ICONSTOP);
      return -1;   /* SJ - This really needs to return a value, which is picked up in */
                   /*      DevSW_Read as meaning stop debugger but don't kill. */
  }
#else
  nwritten = Unix_WriteSerial(wstate.writebuf, wstate.wbindex);

  if (nwritten < 0) {
    nwritten=0;
  }
#endif

#ifdef DEBUG
  if (nwritten > 0)
    printf("Wrote %#04x bytes\n", nwritten);
#endif

  if ((unsigned) nwritten == wstate.wbindex && 
      (testatus == TS_DONE_PKT || testatus == TS_IDLE)) {

    /* finished sending the packet */

#ifdef DEBUG
    printf("SerialWrite: calling Angel_TxEngineInit after sending packet (len=%i)\n",wstate.wbindex);
#endif
    testatus = TS_IN_PKT;
    wstate.wbindex = 0;
    return 1;
  }
  else {
#ifdef DEBUG
    printf("SerialWrite: Wrote part of packet wbindex=%i, nwritten=%i\n",
           wstate.wbindex, nwritten);
#endif
   
    /*
     *  still some data left to send shuffle whats left down and reset
     * the ptr
     */
    memmove((char *) wstate.writebuf, (char *) (wstate.writebuf+nwritten),
            wstate.wbindex-nwritten);
    wstate.wbindex -= nwritten;
    return 0;
  }
  return -1;
}


static int serial_reset( void )
{
#ifdef DEBUG
    printf( "serial_reset\n" );
#endif

#ifdef COMPILING_ON_WINDOWS
    FlushSerial();
#else
    Unix_ResetSerial();
#endif

    return serial_set_params( &serial_defaults );
}


static int find_baud_rate( unsigned int *speed )
{
    static struct {
          unsigned int baud;
          int termiosValue;
    } possibleBaudRates[] = {
#if defined(__hpux)
        {115200,_B115200}, {57600,_B57600},
#else
#ifdef B115200
        {115200,B115200},
#endif
#ifdef B57600
	{57600,B57600},
#endif
#endif
#ifdef COMPILING_ON_WINDOWS
        {38400,CBR_38400}, {19200,CBR_19200}, {9600, CBR_9600}, {0,0}
#else
        {38400,B38400}, {19200,B19200}, {9600, B9600}, {0,0}
#endif
    };
    unsigned int i;

    /* look for lower or matching -- will always terminate at 0 end marker */
    for ( i = 0; possibleBaudRates[i].baud > *speed; ++i )
       /* do nothing */ ;

    if ( possibleBaudRates[i].baud > 0 )
       *speed = possibleBaudRates[i].baud;

    return possibleBaudRates[i].termiosValue;
}


static int serial_set_params( const ParameterConfig *config )
{
    unsigned int speed;
    int termios_value;

#ifdef DEBUG
    printf( "serial_set_params\n" );
#endif

    if ( ! Angel_FindParam( AP_BAUD_RATE, config, &speed ) )
    {
#ifdef DEBUG
        printf( "speed not found in config\n" );
#endif
        return DE_OKAY;
    }

    termios_value = find_baud_rate( &speed );
    if ( termios_value == 0 )
    {
#ifdef DEBUG
        printf( "speed not valid: %u\n", speed );
#endif
        return DE_OKAY;
    }

#ifdef DEBUG
    printf( "setting speed to %u\n", speed );
#endif

#ifdef COMPILING_ON_WINDOWS
    SetBaudRate((WORD)termios_value);
#else
    Unix_SetSerialBaudRate(termios_value);
#endif

    return DE_OKAY;
}


static int serial_get_user_params( ParameterOptions **p_options )
{
#ifdef DEBUG
    printf( "serial_get_user_params\n" );
#endif

    if ( user_options_set )
    {
        *p_options = &user_options;
    }
    else
    {
        *p_options = NULL;
    }

    return DE_OKAY;
}


static int serial_get_default_params( ParameterConfig **p_config )
{
#ifdef DEBUG
    printf( "serial_get_default_params\n" );
#endif

    *p_config = (ParameterConfig *) &serial_defaults;
    return DE_OKAY;
}


static int SerialIoctl(const int opcode, void *args) {

    int ret_code;

#ifdef DEBUG
    printf( "SerialIoctl: op %d arg %p\n", opcode, args ? args : "<NULL>");
#endif

    switch (opcode)
    {
       case DC_RESET:         
           ret_code = serial_reset();
           break;

       case DC_SET_PARAMS:     
           ret_code = serial_set_params((const ParameterConfig *)args);
           break;

       case DC_GET_USER_PARAMS:     
           ret_code = serial_get_user_params((ParameterOptions **)args);
           break;

       case DC_GET_DEFAULT_PARAMS:
           ret_code = serial_get_default_params((ParameterConfig **)args);
           break;

       default:               
           ret_code = DE_BAD_OP;
           break;
    }

  return ret_code;
}

DeviceDescr angel_SerialDevice = {
    "SERIAL",
    SerialOpen,
    SerialMatch,
    SerialClose,
    SerialRead,
    SerialWrite,
    SerialIoctl
};
