

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

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

#include "protocol.h"
#include "bytes.h"
#include "packet.h"
#include "timer.h"

/*#define TI89_MAXTYPES 48
const char *TI89_TYPES[TI89_MAXTYPES]=
{
"EXPR", "UNKNOWN", "UNKNOWN", "UNKNOWN", "LIST", "UNKNOWN", "MAT", "UNKNOWN",
"UNKNOW", "UNKNOWN", "DATA", "TEXT", "STR", "GDB", "FIG", "UNKNOWN",
"PIC", "UNKNOWN", "PRGM", "FUNC", "MAC", "UNKNOWN", "UNKNOWN", "UNKNOWN",
"UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "BACKUP", "UNKNOWN", "DIR",
"ASM", "UNKNOWN", "IDLIST", "UNKNOWN", "FLASH", "UNKNOWN", "LOCKED", "ARCHIVED",
"UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN", "UNKNOWN"
};
*/


#define TI89_TYPE_FLASH 36


struct List_Content
{
  ULONG file_offset;
  char name[MAX_NAMELENGTH+1];
  char foldername[MAX_NAMELENGTH+1];
  char type;
};



char filetypes[] = "e---l-m---ctsda-i-pfx---h----b-g-z---------------r";


int ti_analysedir(Packet *packet, Variable *vars, char removefirst);

int ti_type(char c);
int ti_sendvardata(FILE *fptr, char *folder, char *name, char type);
void ti_writefileheader(FILE *fptr, char *defaultfolder, char *comment, int nb_vars);
void ti_writevarheader(FILE *fptr, char *name, int type, long int offset);
int ti_downloadvar(char *complete_varpath, Packet *data_packet, Variable *var);


/// int ti_ping(int nb)
int ti_ping(int nb)
{
  UBYTE hello[]={0x08,0x68,0x00,0x00};
  Packet packet;
  int cpt;

  ti_initpacket(&packet);

  for ( cpt=1; cpt<=nb;cpt++ )
  {
    //printf("ping %d\n",cpt);
    if ( ti_sendbytes(hello,sizeof(hello)) == 0 )
      if ( ti_getpacket(&packet) == 0 )
        return(TI_OK);

		{
			Timer_Info ti;
			timer_create(&ti);
			timer_delay(&ti,100000L); /* Wait for 0.1s */
			timer_delete(&ti);
		}

  }

  ti_freepacket(&packet);
  return(TI_TIMEOUT);
}
///

/// int ti_analysedir(Packet *packet, Variable *vars, char removefirst)
int ti_analysedir(Packet *packet, Variable *vars, char removefirst)
/*
if removefirst == 1, remove the first entry.
Useful when analysing a folder content, since we have then the folder name
as the first entry, but it is not a variable.
*/
{
  int cpt, nbvar=0;
  unsigned int index=0;

  if ( packet->command != COMMAND_DATA )
    return(TI_PROTOCOL);

  for ( cpt=0; cpt<4; cpt++ )
  {
    if ( packet->bytes[index++] != 0 )
      return(TI_PROTOCOL);
  }

  while ( index < packet->nb )
  {

    for ( cpt=0; cpt<MAX_NAMELENGTH; cpt++ )
      vars[nbvar].name[cpt] = packet->bytes[index++];

    vars[nbvar].name[MAX_NAMELENGTH] = 0;


		//printf("Var %d\n",nbvar);
		//printf(" * Name : %s\n",vars[nbvar].name);

    vars[nbvar].type = packet->bytes[index++];
		//printf(" * Type : %d\n",vars[nbvar].type);
    vars[nbvar].state= packet->bytes[index++];

    vars[nbvar].size = 0;
		//printf(" * Size : ");

    for ( cpt=0; cpt<3; cpt++ )
    { /* Get size on 3 bytes */
			//printf("%x ",packet->bytes[index]);
      vars[nbvar].size += ( (packet->bytes[index++] ) << (8*cpt) );
    }
    index++; /* Skip on byte, unknown use */
		//printf("  = %d\n",vars[nbvar].size);


    if ( removefirst )
      removefirst = 0;
    else
      nbvar++;
  }

  //printf("nb var : %d\n",nbvar);
  return(nbvar);
}
///

/// int ti_listdir(char *foldname, Variable *vars)
int ti_listdir(char *foldname, Variable *vars)
{
  UBYTE ldir_sfx[]={0x00,0x00,0x00,0x1B,0x1A};
  Packet packet;
  UBYTE *ldir;
  UBYTE ok[]={0x08,0x56,0x00,0x00};
  UBYTE waiting[]={0x08,0x09,0x00,0x00};

  unsigned int cpt;
  int nb;

  /*printf("listing %s\n",foldname);*/

  ldir = calloc(sizeof(ldir_sfx)+strlen(foldname)+1,sizeof(UBYTE));

  for ( cpt=0; cpt<sizeof(ldir_sfx); cpt++)
    ldir[cpt] = ldir_sfx[cpt];


  ldir[sizeof(ldir_sfx)] = strlen(foldname);

  for ( cpt=0; cpt<strlen(foldname); cpt++)
    ldir[sizeof(ldir_sfx)+cpt+1]=foldname[cpt];


  ti_initpacket(&packet);
  packet.command = 0xA2;
  ti_cp2packet(&packet,sizeof(ldir_sfx)+strlen(foldname)+1,ldir);


  if ( ti_sendpacket(&packet) )
  {
    ti_freepacket(&packet);
    return(TI_TIMEOUT);
  }


  if (
    ti_getpacket(&packet) ||
    ti_getpacket(&packet) ||
    ti_sendbytes(ok,sizeof(ok)) ||
    ti_sendbytes(waiting,sizeof(waiting)) ||
    ti_getpacket(&packet) ||
    ti_getpacket(&packet) )
  {
      ti_freepacket(&packet);
      return(TI_TIMEOUT);
  }


  nb = ti_analysedir(&packet,vars,1);

  ti_sendbytes(ok,sizeof(ok));
  ti_getpacket(&packet);
  ti_sendbytes(ok,sizeof(ok));

  free(ldir);

  ti_freepacket(&packet);
  return(nb);
}
///

/// int ti_folderlist(Variable *vars)
int ti_folderlist(Variable *vars)
{
  Packet packet;
  UBYTE dir[]={0x00,0x00,0x00,0x1F,0x1A,0x00};
  UBYTE ok[]={0x08,0x56,0x00,0x00};
  UBYTE waiting[]={0x08,0x09,0x00,0x00};
  int nb;

  if ( ti_ping(3) != TI_OK )
    return(TI_PING);

  ti_initpacket(&packet);
  packet.command = 0xA2;
  ti_cp2packet(&packet,sizeof(dir),dir);

  if (  ti_sendpacket(&packet)||
        ti_getpacket(&packet) || /* Skip OK */
        ti_getpacket(&packet) || /* Skip ??? */
        ti_sendbytes(ok,sizeof(ok)) || /* OK... */
        ti_sendbytes(waiting,sizeof(waiting)) || /* ... waiting for data */
        ti_getpacket(&packet) || /* Skip OK */
        ti_getpacket(&packet) ) /* Get listing */
  {
    ti_freepacket(&packet);
    return(TI_TIMEOUT);
  }

  nb = ti_analysedir(&packet,vars,0); /* Analyse it */

  if (  nb < 0 ||
        ti_sendbytes(ok,sizeof(ok)) || /* OK for data  */
        ti_getpacket(&packet) ||  /* Skip EOT */
        ti_sendbytes(ok,sizeof(ok)) ) /* OK */
  {
    ti_freepacket(&packet);
    if ( nb < 0 )  return(nb);
    return(TI_TIMEOUT);
  }

  ti_freepacket(&packet);

  return(nb);

}
///

/// int ti_sendfile(char *filename, char *userfolder)
int ti_sendfile(char *filename, char *userfolder)
{
  char folder[MAX_NAMELENGTH+1];
  int nb_entries;

  FILE *fptr;

  if ( ti_ping(3) != TI_OK )
    return(TI_PING);

  if ((fptr = fopen (filename, "rb")) == NULL )
    return(TI_FILE);

  //printf("Sending %s\n",filename);

  {
    char header[9];
    if ( fread(header,1,8,fptr) != 8 ) /* Read header */
      return(TI_BADFORMAT);
  }
  //printf("header ok\n");

  fgetc(fptr); /* Skip 01 */
  fgetc(fptr); /* Skip 00 */

  if ( fread(folder,1,MAX_NAMELENGTH,fptr) != 8 )
  {
    printf("Cannot read foldername ! \n");
    return(TI_BADFORMAT);
  }
  folder[MAX_NAMELENGTH]=0;
  //printf("folder ok\n");

  {
    char comment[41];
    if ( fread(comment,1,sizeof(comment)-1,fptr) != sizeof(comment)-1 )
      return(TI_BADFORMAT);
  }
  //printf("comment ok\n");

  nb_entries  = fgetc(fptr);
  nb_entries += (fgetc(fptr)<<8);

  /*if ( feof(fptr) )
    return(TI_BADFORMAT);*/

  if ( userfolder[0] ) /* Override default folder with user defined folder */
    strncpy(folder,userfolder,MAX_NAMELENGTH);
  //printf("using %s (%x) \n",folder,folder[0]);

  //printf("nb_entries = %d\n",nb_entries);

  { /* Get variables informations */
    int entry;
    ULONG offset;
    char name[MAX_NAMELENGTH+1];
    char type;


    for ( entry=1; entry <= nb_entries ; entry++ )
    {
      int temp;

      offset = fgetc(fptr);
      offset += fgetc(fptr)<<8;
      offset += fgetc(fptr)<<16;
      offset += fgetc(fptr)<<24;

      //printf("offset   : %x\n",offset);

      if ( (temp=fread(name,1,MAX_NAMELENGTH,fptr)) != MAX_NAMELENGTH )
      {
        printf("impossible de lire le nom (%d/%d) %d\n",temp,MAX_NAMELENGTH,feof(fptr));
        return(TI_BADFORMAT);
      }

      name[MAX_NAMELENGTH] = 0;

      type = fgetc(fptr);
      printf("name(%d) : >%s<\n",entry,name);
      //printf("offset   : %x\n",offset);
      //printf("type     : %x\n",type);
      fgetc(fptr);

      fgetc(fptr); /* Skip 0's */
      fgetc(fptr);

      if ( type != 0x1F )
      {
        long backup_offset = ftell(fptr);
        printf("Jumping to %x\n",offset);
        if ( fseek(fptr,offset, SEEK_SET) )
          return(TI_BADFORMAT);

        {
          int ret;
          if ( (ret=ti_sendvardata(fptr,folder,name, type)) )
            return(ret);
        }

        //printf("back to %x\n",backup_offset);
        if ( fseek(fptr,backup_offset, SEEK_SET) )
          return(TI_BADFORMAT);
      }
      else /* folder info */
      if ( userfolder[0] == '\0' )
      {
        //printf("information supp : folder = <%s>\n",name);
        strncpy(folder,name,MAX_NAMELENGTH);
        folder[MAX_NAMELENGTH] = 0;
      }


    }
  }

  /*system("date");*/
  fclose(fptr);

  return(TI_OK);
}
///

/// int ti_sendvardata(FILE *fptr, char *folder, char *name, char type)
int ti_sendvardata(FILE *fptr, char *folder, char *name, char type)
{

  unsigned short int size;
  UBYTE *buffer;
  UBYTE ok[]={0x08,0x56,0x00,0x00};
  UBYTE eot[]={0x08,0x92,0x00,0x00};
  char fullname[200];
  UBYTE dummy;

  if ( fgetc(fptr)||fgetc(fptr)||fgetc(fptr)||fgetc(fptr) )
  {
    /*printf("pas à 0 ! \n");
    return(1);*/
  }

  size = (fgetc(fptr)<<8) + fgetc(fptr);
  //printf("size : %d (%x)\n",size,size);

  if ( feof(fptr) || size == 0 )
  {
    printf("Error : EOF size=%d\n",size);
    return(TI_BADFORMAT);
  }


  buffer = calloc (size,sizeof(UBYTE));

  if ( fread (buffer,sizeof(UBYTE),size,fptr) != size )
  {
    printf("Could not read %d(%x) bytes in file.\n",size,size);
    free(buffer);
    return(TI_BADFORMAT);
  }

  sprintf(fullname,"%s\\%s",folder,name);
  /*printf("%s\n",fullname);*/


  {
    UBYTE *varhead;
    int index=0;
    unsigned int cpt;
    Packet packet;


    if ( ! ( varhead = calloc(7+strlen(fullname),sizeof(UBYTE)) ) )
      return(TI_MEMORY);

    varhead[index++] = (size+2) & 0xFF;
    varhead[index++] = (size+2) >> 8;
    varhead[index++] = 0;
    varhead[index++] = 0;

    varhead[index++] = type;
    varhead[index++] = strlen(fullname);

    for ( cpt=0; cpt<strlen(fullname); cpt++ )
      varhead[index++] = fullname[cpt];

    varhead[index++] = 0;

    ti_initpacket(&packet);
    packet.command = 0x06;
    ti_cp2packet(&packet,index,varhead);

    if ( ti_sendpacket(&packet) )
    {
      ti_freepacket(&packet);
      return(TI_TIMEOUT);
    }

    if ( ti_getpacket(&packet) ||   /* Skip OK */
         ti_getpacket(&packet) || /* Skip Wait */
         ti_sendbytes(ok,sizeof(ok)) )
    {
      ti_freepacket(&packet);
      return(TI_TIMEOUT);
    }

    ti_freepacket(&packet);
    free(varhead);
  }

  {
    UBYTE *data;
    int cpt,index=0;
    Packet packet;

    if ( ! ( data = calloc(6+size,sizeof(UBYTE)) ) )
      return(TI_MEMORY);

    for ( cpt=0; cpt<4; cpt++ )
      data[index++] = 0;

    data[index++] = size>>8;
    data[index++] = size&0xFF;

    for ( cpt=0; cpt<size; cpt++ )
      data[index++] = buffer[cpt];

    ti_initpacket(&packet);
    packet.command = 0x15;
    ti_cp2packet(&packet,6+size,data);

    ti_sendpacket(&packet);
    ti_freepacket(&packet);

    {
      if (
        ti_recvbyte(&dummy) ||
        ti_recvbyte(&dummy) ||
        ti_recvbyte(&dummy) ||
        ti_recvbyte(&dummy) ) /* Skip OK */
          return(TI_TIMEOUT);
    }

    if ( ti_sendbytes(eot,sizeof(eot)) )
      return(TI_TIMEOUT);

    {
      if (
        ti_recvbyte(&dummy) || /* Skip OK */
        ti_recvbyte(&dummy) || /* Skip OK */
        ti_recvbyte(&dummy) || /* Skip OK */
        ti_recvbyte(&dummy) ) /* Skip OK */
          return(TI_TIMEOUT);
    }

    free(data);
  }

  free(buffer);

  return(TI_OK);
}
///

/// void ti_writefileheader(FILE *fptr, char *defaultfolder, char *comment, int nb_vars)
void ti_writefileheader(FILE *fptr, char *defaultfolder, char *comment, int nb_vars)
{
  char header[]={'*','*','T','I','9','2','*','*','\1','\0'};

  unsigned int cpt;

  for ( cpt=0; cpt<sizeof(header); cpt++) /* Write header */
    fputc(header[cpt],fptr);

  { /* Write folder */
    int flag=0;
    for ( cpt=0; cpt<8; cpt++ ) /* TODO : remove explicit constants */
    {
      if ( ! flag )
        if ( defaultfolder[cpt] == '\0' )
          flag = 1;

      if ( flag )
        fputc('\0' ,fptr);
      else
        fputc(defaultfolder[cpt],fptr);
    }
  }

  { /* Write comment */
    int flag=0;
    for ( cpt=0; cpt<40; cpt++ ) /* TODO : remove explicit constants */
    {
      if ( ! flag )
        if ( comment[cpt] == '\0' )
          flag = 1;

      if ( flag )
        fputc(' ',fptr);
      else
        fputc(comment[cpt],fptr);
    }
  }

  fputc(nb_vars & 0xFF, fptr); /* write nb of vars */
  fputc((nb_vars >> 8)&0xFF, fptr);
}
///

/// void ti_writevarheader(FILE *fptr, char *name, int type, long int offset)
void ti_writevarheader(FILE *fptr, char *name, int type, long int offset)
{
  fputc(offset&0xFF,fptr);
  fputc((offset>>8)&0xFF,fptr);
  fputc((offset>>16)&0xFF,fptr);
  fputc((offset>>24)&0xFF,fptr);


  { /* Write name */
    int flag=0;
    int  cpt;

    for ( cpt=0; cpt<8; cpt++ ) /* TODO : remove explicit constants */
    {
      if ( ! flag )
        if ( name[cpt] == '\0' )
          flag = 1;

      if ( flag )
        fputc('\0' ,fptr);
      else
        fputc(name[cpt],fptr);
    }
  }

  fputc(type&0xFF,fptr);
  fputc((type>>8)&0xFF,fptr);

  fputc(0,fptr);
  fputc(0,fptr);
}
///

/// int ti_getvar(char *foldername, char *varname, char *filename)
int ti_getvar(char *foldername, char *varname, char *filename)
{
  Packet packet;
  //UBYTE ok[]={0x08,0x56,0x00,0x00};
  FILE *fptr;
  unsigned int cpt;

  char complete_varpath[17];

  if ( ti_ping(3) != TI_OK )
    return(TI_PING);

  if ( foldername[0] == '\0' ) // no folder specified
    foldername = "main";


  if ((fptr = fopen (filename, "wb")) == NULL )
  {
    printf("error opening %s\n",filename);
    return(TI_FILE);
  }

  if ( foldername[0] )
    sprintf(complete_varpath,"%s\\%s",foldername,varname);

  //printf("getting %s\n",complete_varpath);



  ti_initpacket(&packet);
  {
    int ret;
    if ( (ret=ti_downloadvar(complete_varpath, &packet, NULL) ) )
    {
      ti_freepacket(&packet);
      return(ret);
    }
  }

  ti_writefileheader(fptr,"main","",1);
  ti_writevarheader(fptr,varname,0x12,0x52);


  /*sprintf(filename,"%s.89%c",varname,filetypes[*//**/

  {
    int index;
    for ( index = 0; index < 4 ; index ++ )
    {
      fputc(((0x52+2+packet.nb)>>(index*8))&0xFF,fptr);;
      /*printf("%x ",head.length[index]);*/
    }
  }

  fputc(0xA5,fptr);
  fputc(0x5A,fptr);
  fputc(0x00,fptr);
  fputc(0x00,fptr);
  fputc(0x00,fptr);
  fputc(0x00,fptr);


  fputc((packet.nb-6)>>8,fptr);
  fputc((packet.nb-6)&0xFF,fptr);

  for ( cpt = 6; cpt < packet.nb ; cpt ++ )
    fputc(packet.bytes[cpt],fptr);

  fputc(0x00,fptr); /* should be checksum */
  fputc(0x00,fptr);

  fclose(fptr);

  ti_freepacket(&packet);

  return(TI_OK);
}
///

/// int ti_getfolder(char *foldername, char *filename)
int ti_getfolder(char *foldername, char *filename)
{
  //UBYTE ok[]={0x08,0x56,0x00,0x00};
  FILE *fptr;
  unsigned long int var, nb_vars;
  static Variable vars[MAX_NBNAME];

  unsigned long int buffer_index=0,buffer_size=0;
  char *buffer;


  char complete_varpath[17];

  if ( ti_ping(3) != TI_OK )
    return(TI_PING);

  if ( foldername[0] == '\0' ) // no folder specified
    foldername = "main";



  if ((fptr = fopen (filename, "wb")) == NULL )
  {
    printf("error opening %s\n",filename);
    return(TI_FILE);
  }

  //printf("getting folder %s\n",foldername);

  if ( (nb_vars = ti_listdir(foldername, vars)) > 0 )
  {
    unsigned long int file_offset;
    Packet packet;
		int nb_real_vars=0; /* number of real vars ( no flash,... ) */


		//printf("%ld vars in folder %s\n",nb_vars,foldername);
    buffer_size = 0;
    for ( var=0 ; var<nb_vars ; var ++)
			if ( vars[var].type != TI89_TYPE_FLASH )
			{
				buffer_size += (vars[var].size+8);
				nb_real_vars++;
			}
    /* In the data part of the file, we found, for each var :
        4     :  zeros
        2     :  length
        length:  variable data
        2     :  checksum
    */

		//printf("Total size of folder : %ld\n",buffer_size);

    if ( (buffer = malloc(buffer_size)) == NULL )
    {
      fclose(fptr);
      return(TI_MEMORY );
    }

		ti_writefileheader(fptr,foldername,"",nb_real_vars);

    ti_initpacket(&packet);

		file_offset=ftell(fptr)+2+16*nb_real_vars;
		//printf("current =%x\n",ftell(fptr));
		//printf("nb_real_vars =%d\n",nb_real_vars);
		//printf("offst = %x\n",file_offset);
		for ( var=0 ; var<nb_real_vars ; var ++)
    {
      int ret;
      unsigned long int cpt;

			if ( vars[var].type == TI89_TYPE_FLASH )
				continue;

      sprintf(complete_varpath,"%s\\%s",foldername,vars[var].name);
      //printf("getting %s  type=%d...",complete_varpath,vars[var].type);
      fflush(stdout);

      ti_writevarheader(fptr,vars[var].name,vars[var].type,file_offset);
      file_offset += (vars[var].size+6);


      if ( ti_ping(3) != TI_OK )
      {
        ti_freepacket(&packet);
        fclose(fptr);
        free(buffer);
        return(TI_PING);
      }

      if ( (ret=ti_downloadvar(complete_varpath, &packet,&(vars[var]) ) ) )
      {
        printf("Error downloading var (%d)\n",ret);
        ti_freepacket(&packet);
        fclose(fptr);
        free(buffer);
        return(ret);
      }
      /* Copy data to buffer */
      for ( cpt = 1; cpt <= 4 ; cpt ++ ) /* Four 0 */
        buffer[buffer_index++] = 0;

      /* Length : */
      vars[var].size -= 2;
      buffer[buffer_index++] = (vars[var].size>>8)&0xFF;
      buffer[buffer_index++] = vars[var].size&0xFF;

      //printf("taille : %d\n",vars[var].size);

      {
        unsigned long int checksum=0;
        /* Data : */
        for ( cpt = 6; cpt < packet.nb ; cpt ++ )
        {
          buffer[buffer_index++] = packet.bytes[cpt];
          checksum += packet.bytes[cpt];
        }
        /* Checksum : */
        buffer[buffer_index++] = checksum&&0xFF;
        buffer[buffer_index++] = (checksum>>8)&&0xFF;
      }

      //printf("Copying data to buffer... ok !\n");
    }
    ti_freepacket(&packet);
  }
  else
  {
    fclose(fptr);
    return(TI_PROTOCOL);
  }

  fputc(0xA5,fptr);
  fputc(0x5A,fptr);


  {
    int cpt;
    for ( cpt = 0; cpt < buffer_index ; cpt ++ )
      fputc(buffer[cpt],fptr);
  }

  fputc(0x00,fptr); // should be checksum
  fputc(0x00,fptr);

  fclose(fptr);

  return(TI_OK);
}
///

/// int ti_downloadvar(char *complete_varpath, Packet *data_packet, Variable *var)
int ti_downloadvar(char *complete_varpath, Packet *data_packet, Variable *var)
{
  int index;
  Packet packet; /* temp. packet */
  UBYTE ok[]={0x08,0x56,0x00,0x00};
  unsigned int cpt;

  /* !!! */
  Variable temp;

  if ( ! var )
    var = &temp; /**/

  ti_initpacket(&packet);
  ti_allocpacket(&packet,6+strlen(complete_varpath));

  index =0;
  packet.command= 0xA2;

  packet.bytes[index++] = 0;
  packet.bytes[index++] = 0;
  packet.bytes[index++] = 0;
  packet.bytes[index++] = 0;

  packet.bytes[index++] = 0;
  packet.bytes[index++] = strlen(complete_varpath);

  for ( cpt=0; cpt<strlen(complete_varpath); cpt++ )
    packet.bytes[index++] = complete_varpath[cpt];

  packet.nb     = index;

  if (     ti_sendpacket(&packet)
        || ti_getpacket(&packet) /*ok */
        ||  packet.bytes[1] != 0x00 )
  {
    printf("No such var\n");
    ti_freepacket(&packet);
    return(TI_NOTEXIST);
  }


  if (      ti_getpacket(&packet)        /* Local name */
        ||  ti_sendbytes(ok,sizeof(ok))) /* OK */
  {
    ti_freepacket(&packet);
    return(TI_PROTOCOL);
  }

  if ( var != NULL )
  { /* update var info */
    int cpt;
    int index=0;

    //for ( cpt=0; cpt<packet.nb; cpt++)
      //printf("%x ",packet.bytes[cpt]);
    //printf("\n");

    var->size = 0;
    for ( cpt=0; cpt<4; cpt++)
      var->size += ( packet.bytes[index++] << (cpt*8));
    //var->size -= 2;

    var->type += packet.bytes[index++];

    for ( cpt=0; cpt<MAX_NAMELENGTH; cpt++)
      var->name[cpt] = packet.bytes[index++];
    //printf("info maj : %s %x %x\n",var->name,var->size,var->type);
  }

  packet.command= COMMAND_WAITING;
  packet.nb     = 0xFFFF;

  if (      ti_sendpacket(&packet) /* waiting */
        ||  ti_getpacket(&packet) /* OK */
        ||  ti_getpacket(data_packet) /* Data */ )
  {
    printf("Error getting var. data\n");
    ti_freepacket(&packet);
    return(TI_PROTOCOL);
  }

  ti_sendbytes(ok,sizeof(ok));

  ti_getpacket(&packet); /* EOT */

  ti_freepacket(&packet);
  return(TI_OK);
}
///

char *ti_code2string(int code)
{
  switch ( code )
  {
    case TI_OK:
      return("No error");
      break;
    case TI_PROTOCOL:
      return("Protocol error.\nPlease report to ocroquette@nordnet.fr");
      break;
    case TI_PING:
      return("The TI did not respond to a ping.\nCheck cable and TI.");
      break;
    case TI_FILE:
      return("File access error.\nPlease check existence and/or rights.");
      break;
    case TI_BADFORMAT:
      return("Error : bad file format.");
      break;
    case TI_MEMORY:
      return("Error : could not allocate memory.");
      break;
    case TI_NOTEXIST:
      return("Error : no such variable.");
      break;
    default:
      return("Timeout.\nThere has been a problem with the transfer.");
      break;
  }
}

