/* 
 * 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$
 *
 *
 * hostchan.c - Semi Synchronous Host side channel interface for Angel.
 */

#include <stdio.h>

#ifdef HAVE_SYS_TIME_H
#  include <sys/time.h>
#else
#  include "winsock.h"
#  include "time.h"
#endif
#include "hsys.h"
#include "host.h"
#include "logging.h"
#include "chandefs.h"
#include "chanpriv.h"
#include "devclnt.h"
#include "buffers.h"
#include "drivers.h"
#include "adperr.h"
#include "devsw.h"
#include "hostchan.h"

#ifndef UNUSED
#define UNUSED(x) (x = x)  /* Silence compiler warnings for unused arguments */
#endif

#define HEARTRATE 5000000

/*
 * list of available drivers, declared in drivers.c
 */
extern DeviceDescr *devices[];

static DeviceDescr *deviceToUse = NULL;

static struct Channel {
    ChannelCallback callback;
    void *callback_state;
} channels[CI_NUM_CHANNELS];

static unsigned char HomeSeq;
static unsigned char OppoSeq;

/*
 * Handler for DC_APPL packets
 */
static DC_Appl_Handler dc_appl_handler = NULL;

/*
 * slots for registered asynchronous processing callback procedures
 */
#define MAX_ASYNC_CALLBACKS 8
static unsigned int             num_async_callbacks = 0;
static Adp_Async_Callback       async_callbacks[MAX_ASYNC_CALLBACKS];

/*
 * writeQueueRoot is the queue of write requests pending acknowledgement
 * writeQueueSend is the queue of pending write requests which will
 * be a subset of the list writeQueueRoot
 */
static Packet *writeQueueRoot = NULL;
static Packet *writeQueueSend = NULL;
static Packet *resend_pkt = NULL;
static int resending = FALSE;

/* heartbeat_enabled is a flag used to indicate whether the heartbeat is
 * currently turned on, heartbeat_enabled will be false in situations
 * where even though a heartbeat is being used it is problematical or
 * dis-advantageous to have it turned on, for instance during the 
 * initial stages of boot up
 */
unsigned int heartbeat_enabled = FALSE;
/* heartbeat_configured is set up by the device driver to indicate whether
 * the heartbeat is being used during this debug session.  In contrast to
 * heartbeat_enabled it must not be changed during a session.  The logic for
 * deciding whether to send a heartbeat is: Is heartbeat_configured for this
 * session? if and only if it is then if heartbeat[is currently]_enabled and
 * we are due to send a pulse then send it 
 */
unsigned int heartbeat_configured = TRUE;

void Adp_initSeq( void ) {
  Packet *tmp_pkt = writeQueueSend;

  HomeSeq = 0;
  OppoSeq = 0;
  if ( writeQueueSend != NULL) {
    while (writeQueueSend->pk_next !=NULL) {
      tmp_pkt = writeQueueSend;
      writeQueueSend = tmp_pkt->pk_next;
      DevSW_FreePacket(tmp_pkt);
    }
  }
  tmp_pkt = writeQueueRoot;
  if ( writeQueueRoot == NULL)
    return;

  while (writeQueueRoot->pk_next !=NULL) {
    tmp_pkt = writeQueueRoot;
    writeQueueRoot = tmp_pkt->pk_next;
    DevSW_FreePacket(tmp_pkt);
  }
  return;
}

/**********************************************************************/

/*
 *  Function: DummyCallback
 *   Purpose: Default callback routine to handle unexpected input
 *              on a channel
 *
 *    Params:
 *       Input: packet  The received packet
 *
 *              state   Contains nothing of significance
 *
 *   Returns: Nothing
 */
static void DummyCallback(Packet *packet, void *state)
{
    ChannelID chan;
    const char fmt[] = "Unexpected read on channel %u, length %d\n";
    char fmtbuf[sizeof(fmt) + 24];

    UNUSED(state);

    chan = *(packet->pk_buffer);
    sprintf(fmtbuf, fmt, chan, packet->pk_length);
    printf(fmtbuf);

    /*
     * junk this packet
     */
    DevSW_FreePacket(packet);
}

/*
 *  Function: BlockingCallback
 *   Purpose: Callback routine used to implement a blocking read call
 *
 *    Params:
 *       Input: packet  The received packet.
 *
 *      Output: state   Address of higher level's pointer to the received
 *                      packet.
 *
 *   Returns: Nothing
 */
static void BlockingCallback(Packet *packet, void *state)
{
    /*
     * Pass the packet back to the caller which requested a packet
     * from this channel.  This also flags the completion of the I/O
     * request to the blocking read call.
     */
    *((Packet **)state) = packet;
}

/*
 *  Function: FireCallback
 *   Purpose: Pass received packet along to the callback routine for
 *              the appropriate channel
 *
 *    Params:
 *       Input: packet  The received packet.
 *
 *   Returns: Nothing
 *
 * Post-conditions: The Target-to-Host sequence number for the channel
 *                      will have been incremented.
 */
static void FireCallback(Packet *packet)
{
    ChannelID chan;
    struct Channel *ch;

    /*
     * is this a sensible channel number?
     */
    chan = *(packet->pk_buffer);
    if (invalidChannelID(chan))
    {
        printf("ERROR: invalid ChannelID received from target\n");

        /*
         * free the packet's resources, 'cause no-one else will
         */
        DevSW_FreePacket(packet);
        return;
    }

    /*
     * looks OK - increment sequence number, and pass packet to callback
     */
    ch = channels + chan;
    (ch->callback)(packet, ch->callback_state);
}

/**********************************************************************/

/*
 * These are the externally visible functions.  They are documented
 * in hostchan.h
 */
void Adp_addToQueue(Packet **head, Packet *newpkt)
{
    /*
     * this is a bit of a hack
     */
    Packet *pk;

    /*
     * make sure that the hack we are about to use will work as expected
     */
    ASSERT(&(((Packet *)0)->pk_next) == 0, "bad struct Packet layout");

#if defined(DEBUG) && 0
    printf("Adp_addToQueue(%p, %p)\n", head, newpkt);
#endif

    /*
     * here's the hack - it relies upon the next
     * pointer being at the start of Packet.
     */
    pk = (Packet *)(head);

    /*
     * skip to the end of the queue
     */
    while (pk->pk_next != NULL)
        pk = pk->pk_next;

    /*
     * now add the new element
     */
    newpkt->pk_next = NULL;
    pk->pk_next = newpkt;
}

Packet *Adp_removeFromQueue(Packet **head)
{
    struct Packet *pk;

    pk = *head;

    if (pk != NULL)
        *head = pk->pk_next;

    return pk;
}

void Adp_SetLogEnable(int logEnableFlag)
{
  DevSW_SetLogEnable(logEnableFlag);
}

void Adp_SetLogfile(const char *filename)
{
  DevSW_SetLogfile(filename);
}

AdpErrs Adp_OpenDevice(const char *name, const char *arg,
                       unsigned int heartbeat_on)
{
    int i;
    AdpErrs retc;
    ChannelID chan;

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

    heartbeat_configured = heartbeat_on;
    if (deviceToUse != NULL)
        return adp_device_already_open;

    for (i = 0; (deviceToUse = devices[i]) != NULL; ++i)
        if (DevSW_Match(deviceToUse, name, arg) == adp_ok)
            break;

    if (deviceToUse == NULL)
        return adp_device_not_found;

    /*
     * we seem to have found a suitable device driver, so try to open it
     */
    if ((retc = DevSW_Open(deviceToUse, name, arg, DC_DBUG)) != adp_ok)
    {
        /* we don't have a device to use */
        deviceToUse = NULL;
        return retc;
    }

    /*
     * there is no explicit open on channels any more, so
     * initialise state for all channels.
     */
    for (chan = 0; chan < CI_NUM_CHANNELS; ++chan)
    {
        struct Channel *ch = channels + chan;

        ch->callback = DummyCallback;
        ch->callback_state = NULL;
        OppoSeq = 0;
        HomeSeq = 0;
    }

    return adp_ok;
}

AdpErrs Adp_CloseDevice(void)
{
    AdpErrs retc;

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

    if (deviceToUse == NULL)
        return adp_device_not_open;

    heartbeat_enabled = FALSE;

    retc = DevSW_Close(deviceToUse, DC_DBUG);

    /*
     * we have to clear deviceToUse, even when the lower layers
     * faulted the close, otherwise the condition will never clear
     */
    if (retc != adp_ok)
        WARN("DevSW_Close faulted the call");

    deviceToUse = NULL;
    return retc;
}

AdpErrs Adp_Ioctl(int opcode, void *args)
{
#ifdef DEBUG
    printf("Adp_Ioctl\n");
#endif

    if (deviceToUse == NULL)
        return adp_device_not_open;

    return DevSW_Ioctl(deviceToUse, opcode, args);
}

AdpErrs Adp_ChannelRegisterRead(const ChannelID chan,
                                const ChannelCallback cbfunc,
                                void *cbstate)
{
#ifdef DEBUG
    printf("Adp_ChannelRegisterRead(%d, %p, %x)\n", chan, cbfunc, cbstate);
#endif

    if (deviceToUse == NULL)
        return adp_device_not_open;

    if (invalidChannelID(chan))
        return adp_bad_channel_id;

    if (cbfunc == NULL)
    {
        channels[chan].callback = DummyCallback;
        channels[chan].callback_state = NULL;
    }
    else
    {
        channels[chan].callback = cbfunc;
        channels[chan].callback_state = cbstate;
    }

    return adp_ok;
}

AdpErrs Adp_ChannelRead(const ChannelID chan, Packet **packet)
{
    struct Channel *ch;

#ifdef DEBUG
    printf("Adp_ChannelRead(%d, %x)\n", chan, *packet);
#endif

    if (deviceToUse == NULL)
        return adp_device_not_open;

    if (invalidChannelID(chan))
        return adp_bad_channel_id;

    /*
     * if a callback has already been registered for this
     * channel, then we do not allow this blocking read.
     */
    ch = channels + chan;
    if (ch->callback != DummyCallback)
        return adp_callback_already_registered;

    /*
     * OK, use our own callback to wait for a packet to arrive
     * on this channel
     */
    ch->callback = BlockingCallback;
    ch->callback_state = packet;
    *packet = NULL;

    /*
     * keep polling until a packet appears for this channel
     */
    while (((volatile Packet *)(*packet)) == NULL)
        /*
         * this call will block until a packet is read on any channel
         */
        Adp_AsynchronousProcessing(async_block_on_read);

    /*
     * OK, the packet has arrived: clear the callback
     */
    ch->callback = DummyCallback;
    ch->callback_state = NULL;

    return adp_ok;
}

static AdpErrs ChannelWrite(
    const ChannelID chan, Packet *packet, AsyncMode mode)
{
    struct Channel *ch;
    unsigned char *cptr;

#ifdef DEBUG
    printf( "Adp_ChannelWrite(%d, %x)\n", chan, packet );
#endif

    if (deviceToUse == NULL)
        return adp_device_not_open;

    if (invalidChannelID(chan))
        return adp_bad_channel_id;

    /*
     * fill in the channels header at the start of this buffer
     */
    ch = channels + chan;
    cptr = packet->pk_buffer;
    *cptr++ = chan;
    *cptr = 0;
    packet->pk_length += CHAN_HEADER_SIZE;

    /*
     * OK, add this packet to the write queue, and try to flush it out
     */

    Adp_addToQueue(&writeQueueSend, packet);
    Adp_AsynchronousProcessing(mode);

    return adp_ok;
}

AdpErrs Adp_ChannelWrite(const ChannelID chan, Packet *packet) {
  return ChannelWrite(chan, packet, async_block_on_write);
}

AdpErrs Adp_ChannelWriteAsync(const ChannelID chan, Packet *packet) {
  return ChannelWrite(chan, packet, async_block_on_nothing);
}

static AdpErrs send_resend_msg(DeviceID devid) {

  /*
   * Send a resend message, usually in response to a bad packet or
   * a resend request */
  Packet * packet;
  packet = DevSW_AllocatePacket(CF_DATA_BYTE_POS);
  packet->pk_buffer[CF_CHANNEL_BYTE_POS] = CI_PRIVATE;
  packet->pk_buffer[CF_HOME_SEQ_BYTE_POS] = HomeSeq;
  packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS] = OppoSeq;
  packet->pk_buffer[CF_FLAGS_BYTE_POS] = CF_RELIABLE | CF_RESEND;
  packet->pk_length = CF_DATA_BYTE_POS;
  return DevSW_Write(deviceToUse, packet, devid);
}

static AdpErrs check_seq(unsigned char msg_home, unsigned char msg_oppo) {
  Packet *tmp_pkt;

  UNUSED(msg_oppo);
  /* 
   * check if we have got an ack for anything and if so remove it from the
   * queue
   */
  if (msg_home == (unsigned char)(OppoSeq+1)) {
    /*
     * arrived in sequence can increment our opposing seq number and remove
     * the relevant packet from our queue
     * check that the packet we're going to remove really is the right one
     */
    tmp_pkt = writeQueueRoot;
    while ((tmp_pkt->pk_next != NULL) &&
           (tmp_pkt->pk_next->pk_buffer[CF_HOME_SEQ_BYTE_POS]
            != OppoSeq)){
      tmp_pkt = tmp_pkt->pk_next;
    }
    OppoSeq++;
    if (tmp_pkt->pk_next == NULL) {
#ifdef DEBUG
      printf("trying to remove a non existant packet\n");
#endif
      return adp_bad_packet;
    }
    else {
      Packet *tmp = tmp_pkt->pk_next;
#ifdef RET_DEBUG
      printf("removing a packet from the root queue\n");
#endif
      tmp_pkt->pk_next = tmp_pkt->pk_next->pk_next;
      /* remove the appropriate packet */
      DevSW_FreePacket(tmp);
    return adp_ok;
    }
  }
  else if (msg_home < (unsigned char) (OppoSeq+1)){
    /* already received this message */
#ifdef RET_DEBUG
    printf("sequence numbers low\n");
#endif   
    return adp_seq_low;
  }
  else {  /* we've missed something */
#ifdef RET_DEBUG
    printf("sequence numbers high\n");
#endif   
    return adp_seq_high;
  }
}

static unsigned long tv_diff(const struct timeval *time_now, 
                             const struct timeval *time_was)
{
    return (  ((time_now->tv_sec * 1000000) + time_now->tv_usec)
            - ((time_was->tv_sec * 1000000) + time_was->tv_usec) );
}

#if !defined(__unix) && !defined(__CYGWIN__)
static void gettimeofday( struct timeval *time_now, void *dummy )
{
    time_t t = clock();
    UNUSED(dummy);
    time_now->tv_sec = t/CLOCKS_PER_SEC;
    time_now->tv_usec = (t%CLOCKS_PER_SEC)*(1000000/CLOCKS_PER_SEC);
}
#endif

static AdpErrs pacemaker(void)
{
  Packet *packet;

  packet = DevSW_AllocatePacket(CF_DATA_BYTE_POS);
  if (packet == NULL) {
    printf("ERROR: could not allocate a packet in pacemaker()\n");
    return adp_malloc_failure;
  }
  packet->pk_buffer[CF_CHANNEL_BYTE_POS] = CI_PRIVATE;
  packet->pk_buffer[CF_HOME_SEQ_BYTE_POS] = HomeSeq;
  packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS] = OppoSeq;
  packet->pk_buffer[CF_FLAGS_BYTE_POS] = CF_RELIABLE | CF_HEARTBEAT;
  packet->pk_length = CF_DATA_BYTE_POS;
  return DevSW_Write(deviceToUse, packet, DC_DBUG);
}  

#ifdef FAKE_BAD_LINE_RX
static AdpErrs fake_bad_line_rx( const Packet *const packet, AdpErrs adp_err )
{
    static unsigned int bl_num = 0;

    if (     (packet != NULL)
          && (bl_num++ >= 20 )
          && ((bl_num % FAKE_BAD_LINE_RX) == 0))
    {
        printf("DEBUG: faking a bad packet\n");
        return adp_bad_packet;
    }
    return adp_err;
}
#endif /* def FAKE_BAD_LINE_RX */

#ifdef FAKE_BAD_LINE_TX
static unsigned char tmp_ch;

static void fake_bad_line_tx( void )
{
    static unsigned int bl_num = 0;

    /* give the thing a chance to boot then try corrupting stuff */
    if ( (bl_num++ >= 20) && ((bl_num % FAKE_BAD_LINE_TX) == 0)) 
    {
        printf("DEBUG: faking a bad packet for tx\n");
        tmp_ch = writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS];
        writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS] = 77;
    }
}

static void unfake_bad_line_tx( void )
{
    static unsigned int bl_num = 0;

    /*
     * must reset the packet so that its not corrupted when we
     *  resend it 
     */   
    if ( (bl_num >= 20) && ((bl_num % FAKE_BAD_LINE_TX) != 0))
    {
        writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS] = tmp_ch;
    }
}
#endif /* def FAKE_BAD_LINE_TX */

/*
 * NOTE: we are assuming that a resolution of microseconds will
 * be good enough for the purporses of the heartbeat.  If this proves
 * not to be the case then we may need a rethink, possibly using
 * [get,set]itimer
 */
static struct timeval time_now;
static struct timeval time_lastalive;

static void async_process_dbug_read( const AsyncMode mode,
                                     bool *const finished  )
{
    Packet *packet;
    unsigned int msg_home, msg_oppo;
    AdpErrs adp_err;

    adp_err = DevSW_Read(deviceToUse, DC_DBUG, &packet,
                         mode == async_block_on_read    );

#ifdef FAKE_BAD_LINE_RX
    adp_err = fake_bad_line_rx( packet, adp_err );
#endif

    if (adp_err == adp_bad_packet) {
        /* We got a bad packet, ask for a resend, send a resend message */
#ifdef DEBUG
        printf("received a bad packet\n");
#endif
        send_resend_msg(DC_DBUG);
    }
    else if (packet != NULL)
    {
        /* update the heartbeat clock */
        gettimeofday(&time_lastalive, NULL);

            /*
             * we got a live one here - were we waiting for it?
             */
        if (mode == async_block_on_read)
           /* not any more */
           *finished = TRUE;
#ifdef RETRANS

        if (packet->pk_length < CF_DATA_BYTE_POS) {
            /* we've got a packet with no header information! */
            printf("ERROR: packet with no transport header\n");
            send_resend_msg(DC_DBUG);
        }
        else {
#ifdef RET_DEBUG
            unsigned int c;
#endif
            /*
             * TODO: Check to see if its acknowledgeing anything, remove
             * those packets it is from the queue.  If its a retrans add the
             * packets to the queue
             */
            msg_home = packet->pk_buffer[CF_HOME_SEQ_BYTE_POS];
            msg_oppo = packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS];
#ifdef RET_DEBUG
            printf("msg seq numbers are hseq 0x%x oseq 0x%x\n",
                   msg_home, msg_oppo);
            for (c=0;c<packet->pk_length;c++)
               printf("%02.2x", packet->pk_buffer[c]);
            printf("\n");
#endif
            /* now was it a resend request? */
            if ((packet->pk_buffer[CF_FLAGS_BYTE_POS]) 
                & CF_RESEND) {
                /* we've been asked for a resend so we had better resend */
                /*
                 * I don't think we can use a resend as acknowledgement for
                 * anything so lets not do this for the moment
                 * check_seq(msg_home, msg_oppo);
                 */
#ifdef RET_DEBUG
                printf("received a resend request\n");
#endif
                if (HomeSeq != msg_oppo) {
                    int found = FALSE;
                    /* need to resend from msg_oppo +1 upwards */
                    DevSW_FreePacket(packet);
                    resending = TRUE;
                    /* find the correct packet to resend from */
                    packet = writeQueueRoot;
                    while (((packet->pk_next) != NULL) && !found) {
                        if ((packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS])
                            != msg_oppo+1) {
                            resend_pkt = packet;
                            found = TRUE;
                        }
                        packet = packet->pk_next;
                    }
                    if (!found) {
                        panic("trying to resend non-existent packets\n");
                    }
                }
                else if (OppoSeq != msg_home) {
                    /* 
                     * send a resend request telling the target where we think
                     * the world is at 
                     */
                    DevSW_FreePacket(packet);
                    send_resend_msg(DC_DBUG);
                }
            }
            else {
                /* not a resend request, lets check the sequence numbers */
                
                if ((packet->pk_buffer[CF_CHANNEL_BYTE_POS] != CI_HBOOT) &&
                    (packet->pk_buffer[CF_CHANNEL_BYTE_POS] != CI_TBOOT)) {
                    adp_err = check_seq(msg_home, msg_oppo);
                    if (adp_err == adp_seq_low) {
                        /* we have already received this packet so discard */
                        DevSW_FreePacket(packet);
                    }
                    else if (adp_err == adp_seq_high) {
                        /*
                         * we must have missed a packet somewhere, discard this 
                         * packet and tell the target where we are
                         */
                        DevSW_FreePacket(packet);
                        send_resend_msg(DC_DBUG);
                    }
                    else
                       /*
                        * now pass the packet to whoever is waiting for it
                        */
                       FireCallback(packet);
                }
                else
                   FireCallback(packet);
            }
        }
#else
        /*
             * now pass the packet to whoever is waiting for it
             */
        FireCallback(packet);
#endif
    }
}

static void async_process_appl_read(void)
{
    Packet *packet;
    AdpErrs adp_err;

    /* see if there is anything for the DC_APPL channel */
    adp_err = DevSW_Read(deviceToUse, DC_APPL, &packet, FALSE);

    if (adp_err == adp_ok && packet != NULL)
    {
        /* got an application packet on a shared device */

#ifdef DEBUG
        printf("GOT DC_APPL PACKET: len %d\nData: ", packet->pk_length);
        {
            unsigned int c;
            for ( c = 0; c < packet->pk_length; ++c )
               printf( "%02X ", packet->pk_buffer[c] );
        }
        printf("\n");
#endif

        if (dc_appl_handler != NULL)
        {
            dc_appl_handler( deviceToUse, packet );
        }
        else
        {
            /* for now, just free it!! */
#ifdef DEBUG
            printf("no handler - dropping DC_APPL packet\n");
#endif
            DevSW_FreePacket( packet );
        }
    }
}

static void async_process_write( const AsyncMode mode,
                                 bool *const finished  )
{
    Packet *packet;

#ifdef DEBUG
    static unsigned int num_written = 0;
#endif

    /*
     * NOTE: here we rely in the fact that any packet in the writeQueueSend
     * section of the queue will need its sequence number setting up while
     * and packet in the writeQueueRoot section will have its sequence
     * numbers set up from when it was first sent so we can easily look
     * up the packet numbers when(if) we want to resend the packet.
     */

#ifdef DEBUG
    if (writeQueueSend!=NULL)
       printf("written 0x%x\n",num_written += writeQueueSend->pk_length);
#endif
    /*
     * give the switcher a chance to complete any partial writes
     */
    if (DevSW_FlushPendingWrite(deviceToUse) == adp_write_busy)
    {
        /* no point trying a new write */
        return;
    }
      
    /*
     * now see whether there is anything to write
     */
    packet = NULL;
    if (resending) {
        packet = resend_pkt;
#ifdef RET_DEBUG
        printf("resending hseq 0x%x oseq 0x%x\n", 
               packet->pk_buffer[CF_HOME_SEQ_BYTE_POS],
               packet->pk_buffer[CF_OPPO_SEQ_BYTE_POS]);
#endif
    }
    else if (writeQueueSend != NULL) {
#ifdef RETRANS
        /* set up the sequence number on the packet */
        packet = writeQueueSend;
        HomeSeq++;
        (writeQueueSend->pk_buffer[CF_OPPO_SEQ_BYTE_POS])
            = OppoSeq;
        (writeQueueSend->pk_buffer[CF_HOME_SEQ_BYTE_POS])
            = HomeSeq;
        (writeQueueSend->pk_buffer[CF_FLAGS_BYTE_POS])
            = CF_RELIABLE;
# ifdef RET_DEBUG
        printf("sending packet with hseq 0x%x oseq 0x%x\n",
               writeQueueSend->pk_buffer[CF_HOME_SEQ_BYTE_POS],
               writeQueueSend->pk_buffer[CF_OPPO_SEQ_BYTE_POS]);
# endif
#endif /* RETRANS */
    }

    if (packet != NULL) {
        AdpErrs dev_err;

#ifdef FAKE_BAD_LINE_TX
        fake_bad_line_tx();
#endif

        dev_err = DevSW_Write(deviceToUse, packet, DC_DBUG);
        if (dev_err == adp_ok) {
#ifdef RETRANS
            if (resending) {
                /* check to see if we've recovered yet */
                if ((packet->pk_next) == NULL){
# ifdef RET_DEBUG
                    printf("we have recovered\n");
# endif
                    resending = FALSE;
                }
                else {
                    resend_pkt = resend_pkt->pk_next;
                }
            }
            else {
                /* 
                 * move the packet we just sent from the send queue to the root
                 */
                Packet *tmp_pkt, *tmp;

# ifdef FAKE_BAD_LINE_TX
                unfake_bad_line_tx();
# endif

                tmp_pkt = writeQueueSend;
                writeQueueSend = writeQueueSend->pk_next;
                tmp_pkt->pk_next = NULL;
                if (writeQueueRoot == NULL)
                   writeQueueRoot = tmp_pkt;
                else {
                    tmp = writeQueueRoot;
                    while (tmp->pk_next != NULL) {
                        tmp = tmp->pk_next;
                    }
                    tmp->pk_next = tmp_pkt;
                }
            }
#else  /* not RETRANS */
            /*
             * switcher has taken the write, so remove it from the
             * queue, and free its resources
             */
            DevSW_FreePacket(Adp_removeFromQueue(&writeQueueSend));
#endif /* if RETRANS ... else ... */

            if (mode == async_block_on_write)
               *finished = DevSW_WriteFinished(deviceToUse);

        } /* endif write ok */
    }
    else /* packet == NULL */
    {
        if (mode == async_block_on_write)
           *finished = DevSW_WriteFinished(deviceToUse);
    }
}

static void async_process_heartbeat( void )
{
    /* check to see whether we need to send a heartbeat */
    gettimeofday(&time_now, NULL);

    if (tv_diff(&time_now, &time_lastalive) >= HEARTRATE)
    {
        /*
         * if we've not booted then don't do send a heartrate the link
         * must be reliable enough for us to boot without any clever stuff,
         * if we can't do this then theres little chance of the link staying
         * together even with the resends etc
         */
        if (heartbeat_enabled) {
            gettimeofday(&time_lastalive, NULL);
            pacemaker();
        }
    }
}

static void async_process_callbacks( void )
{
    /* call any registered asynchronous callbacks */
    unsigned int i;
    for ( i = 0; i < num_async_callbacks; ++i )
       async_callbacks[i]( deviceToUse, &time_now );
}

void Adp_AsynchronousProcessing(const AsyncMode mode)
{
    bool finished = FALSE;
#ifdef DEBUG
    unsigned int wc = 0, dc = 0, ac = 0, hc = 0;
# define INC_COUNT(x) ((x)++)
#else
# define INC_COUNT(x)
#endif

    if ((time_lastalive.tv_sec == 0) && (time_lastalive.tv_usec == 0)) {
      /* first time through, needs initing */
      gettimeofday(&time_lastalive, NULL);
    }

    /* main loop */
    do
    {
        async_process_write( mode, &finished );
        INC_COUNT(wc);

        if ( ! finished && mode != async_block_on_write )
        {
            async_process_dbug_read( mode, &finished );
            INC_COUNT(dc);
        }

        if ( ! finished && mode != async_block_on_write )
        {
           async_process_appl_read();
           INC_COUNT(ac);
        }

        if ( ! finished )
        {
          if (heartbeat_configured)
            async_process_heartbeat();
          async_process_callbacks();
          INC_COUNT(hc);
        }

    } while (!finished && mode != async_block_on_nothing);

#ifdef DEBUG
    if ( mode != async_block_on_nothing )
       printf( "Async: %s - w %d, d %d, a %d, h %d\n",
               mode == async_block_on_write ? "blk_write" : "blk_read",
               wc, dc, ac, hc );
#endif
}

/*
 * install a handler for DC_APPL packets (can be NULL), returning old one.
 */
DC_Appl_Handler Adp_Install_DC_Appl_Handler(const DC_Appl_Handler handler)
{
    DC_Appl_Handler old_handler = dc_appl_handler;

#ifdef DEBUG
    printf( "Installing DC_APPL handler %x (old %x)\n", handler, old_handler );
#endif

    dc_appl_handler = handler;
    return old_handler;
}


/*
 * add an asynchronous processing callback to the list
 * TRUE == okay, FALSE == no more async processing slots
 */
bool Adp_Install_Async_Callback( const Adp_Async_Callback callback_proc )
{
    if ( num_async_callbacks < MAX_ASYNC_CALLBACKS && callback_proc != NULL )
    {
        async_callbacks[num_async_callbacks] = callback_proc;
        ++num_async_callbacks;
        return TRUE;
    }
    else
       return FALSE;
}


/*
 * delay for a given period (in microseconds)
 */
void Adp_delay(unsigned int period)
{
    struct timeval tv;

#ifdef DEBUG
    printf("delaying for %d microseconds\n", period);
#endif
    tv.tv_sec = (period / 1000000);
    tv.tv_usec = (period % 1000000);

    (void)select(0, NULL, NULL, NULL, &tv);
}

/* EOF hostchan.c */
