#include "archinc.h"
/* #include "timer0.h" // for 3-second delay */
/* #include "uart0.h" */
#include "crc16.h"
#include "xmodem.h"

#ifdef CONFIG_INCLUDE_XMODEM

/*
 * This is a simple, xmodem receive-only module. It recei
 */
#define XMODEM_SOH (0x01) // Start of Header
#define XMODEM_EOT (0x04) // End of Transmission
#define XMODEM_ACK (0x06) // Acknowledge
#define XMODEM_NAK (0x15) // Negative Acknowledge
#define XMODEM_C   (0x43) // ASCII 'C'

#define XMODEM_PACKET_SIZE (256)
#define XMODEM_MAX_SYNC_RETRIES (10)

static unsigned char packetSeqNum;

static char packet[XMODEM_PACKET_SIZE];

typedef enum {expectSOH, expectPktSeqNum, expectPsnCksum, expectCRC} xmodemReceiverState;

static xmodemReceiverState rcvState;

static void flushReceive(void)
{
}

void xmodemInit(void)
{
  rcvState  = expectSOH;
  packetSeqNum = 0;
}

int xmodemReceive(char * rcvMem)
{
  int syncRetryCount = 0;

  // switch console RX events to receiveEventHandler()

  // flush console receive buffer

  // TODO: need some sort of a timeout here
  while ((rcvState == expectSOH) && 
         (syncRetryCount < XMODEM_MAX_SYNC_RETRIES)) {
    // TODO: send XMODEM_C
    // check to see if we have received characters
    // if (chars received) exit and let the event handler take over
    // else wait 3 seconds bump retry count and send XMODEM_C again
    }

  return ((rcvState == expectSOH) ? -1 : 0);
}

void receiveEventHandler(void)
{
  char inCh;

  // TODO: get character

  switch(rcvState) {
    case expectSOH:
      if (inCh == XMODEM_SOH) {
        rcvState = expectPktSeqNum;
        }
      break;
    case expectPktSeqNum:
      // TODO: check to see that seq num received is not a duplicate
      rcvState = expectPsnCksum;
      break;
    case expectPsnCksum:
      break;
    case expectCRC:
      break;
    }
}

#endif /* CONFIG_INCLUDE_XMODEM */

