
/* ANSI */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

/* Amiga */
#include <exec/types.h>

#include "packet.h"
#include "bytes.h"


int ti_sendpacket(Packet *packet)
{
  unsigned int cpt;
  WORD checksum=0;

  if ( ti_sendbyte(0x08) )
    return(PACKET_ERROR);
  if ( ti_sendbyte(packet->command) )
    return(PACKET_ERROR);
  if ( ti_sendbyte(packet->nb&0xFF) )
    return(PACKET_ERROR);
  if ( ti_sendbyte(packet->nb>>8) )
    return(PACKET_ERROR);

  if ( packet->command != COMMAND_WAITING )
  for ( cpt=1; cpt<=packet->nb; cpt++)
  {
    if ( ti_sendbyte(packet->bytes[cpt-1]) )
      return(PACKET_ERROR);
    checksum += packet->bytes[cpt-1];
  }

  if ( packet->command != COMMAND_WAITING )
  if ( packet->nb )
  {
    if ( ti_sendbyte(checksum&0xFF) )
      return(PACKET_ERROR);
    if ( ti_sendbyte((checksum>>8)&0xFF) )
      return(PACKET_ERROR);
  }

  return(0);
}

int ti_getpacket(Packet *packet)
{
  UBYTE temp;

  if ( ti_recvbyte(&temp) || temp != 0x98 )
    return(PACKET_ERROR);


  if ( ti_recvbyte(&packet->command) )
    return(PACKET_ERROR);

  {
    unsigned int nb;
    if ( ti_recvbyte(&temp) )
      return(PACKET_ERROR);

    nb=temp;

    if ( ti_recvbyte(&temp) )
      return(PACKET_ERROR);

    nb += (temp << 8);

    if ( nb > packet->max ) /* Not enough memory, realloc */
      if ( ti_allocpacket(packet,nb) )
        return(PACKET_ERROR);

    packet->nb = nb;
  }


  if ( packet->nb && packet->command != COMMAND_OK)
  {
    unsigned int cpt;
    unsigned short int checksum=0;
    unsigned short int recv_checksum;

    for ( cpt=0; cpt<packet->nb; cpt++ )
    {
      if ( ti_recvbyte(&packet->bytes[cpt]) )
        return(PACKET_ERROR);
      checksum += packet->bytes[cpt];
    }

    ti_recvbyte(&temp);
    recv_checksum = temp;

    ti_recvbyte(&temp);
    recv_checksum += temp<<8;


    if ( recv_checksum != checksum )
    {
      printf("Error : checksum %x!=%x\n",recv_checksum,checksum);
      return(PACKET_ERROR);
    }

    packet->checksum = checksum;
  }


  return(0);
}

int ti_cp2packet(Packet *packet, int nb, UBYTE *bytes)
{
  unsigned int cpt;
  if ( (unsigned int)nb > packet->max )
    if ( ti_allocpacket(packet,nb) )
      return(PACKET_ERROR);

  for ( cpt=0; cpt<(unsigned int)nb ; cpt ++ )
    packet->bytes[cpt] = bytes[cpt];

  packet->nb = nb;

  return(0);

}

void ti_initpacket(Packet *packet)
{
  packet->max = 0;
  packet->nb  = 0;
  packet->bytes = NULL;
}

int ti_allocpacket(Packet *packet, int nb)
{
  ti_freepacket(packet);

  packet->bytes = calloc(nb,sizeof(UBYTE));

  if ( ! packet->bytes && nb )
  {
    packet->max = 0;
    packet->nb  = 0;
    return(PACKET_ERROR);
  }

  packet->max = nb;
  return(0);
}


void ti_freepacket(Packet *packet )
{
  if ( packet->bytes && packet->max)
    free(packet->bytes );
  packet->bytes = NULL;
  packet->nb  = 0 ;
  packet->max = 0 ;
}

