/*******************************************************************/
/*******************************************************************/
/*            MODULE LECTEUR.C - Handling of reader card           */
/*******************************************************************/

#include <dos.h>
#include <conio.h>
#include <fcntl.h>
#include <io.h>
#include <sys\types.h>
#include <sys\stat.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "defs.h"

#include "..\LibUrne\LibUrne.h"
#include "..\comp\system\system.h"

#include "lecteur.h"

/*******************************************************************/
extern s_Parameters gsParamMgnCdUrne;

extern szMessage *pszMessage_Point;
extern char JETON_ETENDU[_JETON_ETENDU_MAX_BYTE+1];
extern char JETON[_JETON_MAX_BYTE+1];
extern int Table[_E_NB_MAX_VOTE], Table_Val[_E_TABLE_VAL_PLACE];

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

#define _WAIT { unsigned long inc;                     \
 for(inc=CurrentTime();CurrentTime() - inc < (unsigned long) 1;);    \
              }
#define _WAIT2 { unsigned long inc;                     \
 for(inc=CurrentTime();CurrentTime() - inc < (unsigned long) 2;);    \
              }

#define _WAITL { unsigned long inc;                     \
 for(inc=CurrentTime();CurrentTime() - inc < (unsigned long) 5;);    \
              }

int   SECU;
long  SECU_TIMER;
int rang,valrang;

char  etat;
char Command_R1[MAX_BUFFER_VALIDATOR];
char Command_W1[MAX_BUFFER_VALIDATOR];
char Command_R2[100];
char Command_W2[100];
char CARTE_VALID[100];

uchar PORT_2 = 2;
uchar PORT_1 = 1;
/***********************************************/
#define _DUMMY  0

#define _RX_SIZE  4096
#define _TX_SIZE  1024
#define _DEBUT  0

#define _PORT_1  1
#define _PORT_2  2
/****************************************************************************/

uchar PORT_1_BUFFER_IN[_RX_SIZE];
uchar PORT_1_BUFFER_OUT[_TX_SIZE];

int NB_RECOM_1;
int PORT_ACTIVE;

boolean bRecCard;
boolean bBusy;
/****************************************************************************/

extern char System_Used[9];
extern char Chemin_D[25];
extern int iDiskId;
extern boolean bNoSupMode;
extern boolean bStart;
extern boolean bRecount_Mode;
extern boolean bReading_Loop;
extern boolean bWriteData_Ram;

/* Vote counters */
extern int  *piNOMBRE_VOTES1, *piNOMBRE_VOTES2, *piNOMBRE_VOTES3;
extern int  *piNOMBRE_NATIO_VOTES1, *piNOMBRE_NATIO_VOTES2, *piNOMBRE_NATIO_VOTES3;
extern int  *piNOMBRE_STR_VOTES1, *piNOMBRE_STR_VOTES2, *piNOMBRE_STR_VOTES3;
/*****************************************************************************/

int SENS_1;
int PORT_1_NEXT_COMMAND;
int PORT_1_PAST_COMMAND;

int PORT_1_DO_NEXT_SEND;

/*Validator - array of function pointers*/
int ( * PORT_1_COMMAND[]) (uchar *) =
                   {
                     Lecteur_Status_Feed,  /* wait a card */
                     Lecteur_Read,         /* reading the card */
                     Lecteur_Valide,       /* checking the card */
                     Lecteur_Write,        /* writing on the card */
                     Lecteur_Status_Write, /* writing status */
                     Lecteur_Eject,        /* Eject front or rear */
                     Lecteur_Status_Eject, /* eject status */
                     Fin /*allows to return at the first index of array*/
                   };

int SENS_2;
int PORT_2_NEXT_COMMAND;
int PORT_2_DO_NEXT_SEND;

/*Urn - array of function pointers*/
int ( * PORT_2_COMMAND[]) (uchar *) =
                   {
                     Lecteur_Status_Feed,  /* wait a card */
                     Lecteur_Read,         /* reading the card */
                     Lecteur_Enregistre,   /* recover vote contents from the card */
                     Lecteur_Eject,        /* Eject front or rear  */
                     Lecteur_Status_Eject, /* eject status  */
                     Lecteur_Valide_Vote,  /* validate the vote */
                     Lecteur_Get_Position, /* Determine the card position */
                     Lecteur_Vide,          /*Check if reader card is busy*/
                     Fin,                   /*allows to return at the first index of array*/
                     Lecteur_Deblock,      /*Free the reader card*/
                     Lecteur_Status_Deblock /*Free the reader card status*/
                   };

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

uchar CARTE_1[_CARTE_MAX_BYTE+1];
extern   int  C_VOTE_MAX_BYTE;
int First = 0;
int VAR_DEB = 0;
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Do_command</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Execute a function from an array function pointers</DESCRIPTION>
        <PARAMETER>
			<NAME>Command, Port</NAME>
			<TYPE>int, uchar *</TYPE>
			<IO>IN,IN</IO>
			<DESCRIPTION>Command indicate the array index; Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Do_command(int Command, uchar *Port)
{
  int (*funct) (uchar *);
  int status;

  if (Port == &PORT_2)
  {
	  funct = PORT_2_COMMAND[Command];
	  PORT_ACTIVE = _PORT_2;
	  status = (funct)(Port);
  }
  else
  {
      funct = PORT_1_COMMAND[Command];
      PORT_ACTIVE = _PORT_1;
      status = (funct)(Port);
     _WAIT;
   }
  return(status);
} /* do_command */
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Do_command</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Allow to return at the first index of the array of function pointers
		</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>int, uchar *</TYPE>
			<IO>IN,IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return reader is busy</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
#pragma argsused
int Fin(uchar *Port)
{
  if (PORT_ACTIVE == _PORT_2)
    {
      COLOR = _ON_GREEN;
      Light_LED(COLOR);
	  bBusy = false;
      PORT_2_NEXT_COMMAND = _DEBUT;
      PORT_2_DO_NEXT_SEND = true;
      putch(0x07);
    }
  else
    {
      PORT_1_NEXT_COMMAND = _DEBUT;
      PORT_1_DO_NEXT_SEND = true;
    }

  return(_LECTEUR_BUSY);
}
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Read</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>reading the card</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Lecteur_Read(uchar *Port)
{
	LecteurRead(Port);
	return _LECTEUR_GOOD;
} /* Lecteur_Read */

/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Write</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>writing on the card</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Lecteur_Write(uchar *Port)
{
	sprintf(Command_W1,"%s",CARTE_VALID);
	Command_W1[_C_TEST_PLACE] = Type_Multi;  /* writing the type of voter */
	Command_W1[_C_PASSAGE_PLACE] ='0';

	Calcul_Crc(Command_W1,_C_TEST_PLACE);
	Encode_Crc(Command_W1);
	Lcd_Affiche(PORT_ACTIVE, 0, pszMessage_Point[72]);

	LecteurWrite(Port,Command_W1);
	return(_LECTEUR_GOOD);

} /* Lecteur Write */

/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Eject</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Eject card in front or rear direction</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Lecteur_Eject(uchar *Port)
{
	int status;

	if (PORT_ACTIVE == _PORT_1)
	{
		LecteurEject(Port, EJECT_FRONT); /*C_EJECT_FRONT*/
	}
	else
	{
		if (SENS_2 == _PASS_OUT_REAR)
		{
		  LecteurEject(Port, EJECT_REAR); /*C_EJECT_REAR*/
		}
		else
		{
			LecteurEject(Port, EJECT_FRONT); /*C_EJECT_FRONT C_EJECT_FRONT_FAST*/
		}
	}

	return(_LECTEUR_GOOD);
} /* Lecteur_Eject */
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Vide</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Check if reader card is busy</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return reader card status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
#pragma argsused
int Lecteur_Vide(uchar *Port)
{

	if(LecteurVide(Port, Command_R2))
		return(_LECTEUR_BUSY);

	if (Command_R2[1] == '8')
	{
		if ((Command_R2[2] == '4') || (Command_R2[2] == '0'))
		{
			PORT_2_DO_NEXT_SEND = true;
			return(_LECTEUR_GOOD);
		}

		SetTimer(2);
		PORT_2_NEXT_COMMAND = _DEBUT;
		PORT_2_DO_NEXT_SEND = true;
		return(NO_ACTION);
	}

	CloseConnection(Port);
	if(strcmp(System_Used,"JITES") != 0)
	{
		if(Lecteur_2_Init(&gsParamMgnCdUrne))/*PMD*/
		{
			LecteurEject(&PORT_2, EJECT_FRONT);
			PORT_2_NEXT_COMMAND = 6;
		}
		else
		{
			return _TRANSMISSION_ERROR;
		}
	}
	else
	{
		Lecteur_2_Init(&gsParamMgnCdUrne);
		PORT_2_NEXT_COMMAND = 6;
	}

	PORT_2_DO_NEXT_SEND = true;

	return(_LECTEUR_BUSY);


} /* Lecteur_Vide */
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Deblock</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Free the reader card</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return reader card status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
#pragma argsused
int Lecteur_Deblock(uchar *Port)
{
 _WAITL;
 COLOR = COLOR | 0x20;
 LecteurDeblock(Port);

 return(_LECTEUR_GOOD);
}
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Status_Deblock</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Check if card can eject to front or rear direction
		after the reader card is free
		</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return reader card status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
#pragma argsused
int Lecteur_Status_Deblock(uchar *Port)
{
  char choix,Clef[11],/*<< 9.04*/ szTempo[65] /*>>*/;
  int status = 0, iCpt;

  if (LecteurStatusDeblock(Port, Command_R2)) return(_LECTEUR_BUSY);
  status = Test_Retour(Command_R2);
  switch (status)
	{
	  case 0   :
		  if(VAR_DEB >= 15)
		  {
			  /*<< 9.04*/
			  /*Lcd_Affiche(0,0, pszMessage_Point[20]);*/
			  if(strcmp(System_Used,"JITES") == 0)
			  {
				  Lcd_Affiche(0,0, pszMessage_Point[20]);
				  Lcd_Affiche(1,0, pszMessage_Point[21]);
			  }
			  else
			  {
				  /*Lcd_Affiche(1,0, pszMessage_Point[94]);*/
				  sprintf(szTempo,"%s%s",pszMessage_Point[20],pszMessage_Point[94]);
				  Lcd_Affiche(0,0, szTempo);
			  }
			  /*>>*/

			  COLOR = _OFF_RED_GREEN;
			  /* << 9.04 */
			  /*choix = Getch(COLOR);*/
			  choix = ' ';
			  while((choix != 'O') && (choix != 'J') && (choix != 'N'))
				  choix = Getch(COLOR);

			  Lcd_Affiche(0,0, " ");
			  Lcd_Affiche (1, 0, " ");
			  /* >>*/

			  _WAITL;
			  VAR_DEB = 0;

			  if((choix  == 'O') || ( choix  == 'J'))
				 {
				   for(iCpt = 0;(iCpt < 3) && (!status);iCpt++)
					 {
					   status = Demande_Identite(Clef,false);
					   if(!status)
						   break;
					   else
							status = Verifie_Urne(Clef);
					 }

				   /*<< 9.04*/
				   Lcd_Affiche(0,0, " ");
				   Lcd_Affiche (1, 0, " ");
				   /*>>*/

				   if(strcmp(System_Used,"DIGIVOTE") == 0)
					   Video_Screen(SCR_GEN);

					 SetTimer(2);
					 if (status)
					 {
						 /* << 9.04*/
						 /*return(_EJECT_CARD_REAR);*/
						 if((strcmp(System_Used,"JITES") == 0) && (SUPPORT == 'E'))
						 {
							SAUVE_TO_EPROM = false;
							return(_EJECT_CARD);
						 }
						 else
							return(_EJECT_CARD_REAR);
						 /* >>*/
					 }
				 }

			  Lcd_Affiche(0,0, pszMessage_Point[87]);
			  Lcd_Affiche (1, 0, " ");

			  _WAITL;
		   }
		   break;
	}
  VAR_DEB++;
  SENS_2 = _PASS_OUT_FRONT ;

  return(_EJECT_CARD);


} /*  */
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Get_Position</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Determine the card position in the reader</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
#pragma argsused
int Lecteur_Get_Position(uchar *Port)
{
	LecteurGetPosition(Port);
	return(_LECTEUR_GOOD);

} /* Lecteur_Position */
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Put_Tempo</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Order to temporize</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
#pragma argsused
int Lecteur_Put_Tempo()
{
	char status;

	status = LecteurPutTempo(&PORT_1, Command_R1);
	if( Command_R1[0] == 'x' && Command_R1[2] == '0')
		status = 0;
	else
		status = 1;

	switch (status)
	{
	case 0   :
		break;
	default  :
		Lcd_Affiche(0,0, pszMessage_Point[73]);
		Lcd_Affiche(1,0, pszMessage_Point[75]);
		Boucle_Erreur();
	}

	status = LecteurPutTempo(&PORT_2, Command_R2);

	if( Command_R2[0] == 'x' && Command_R2[2] == '0')
		status = 0;
	else
		status = 1;

	switch (status)
	{
	case 0   :
		break;
	default  :
		Lcd_Affiche(0,0,  pszMessage_Point[74]);
		Lcd_Affiche(1,0,  pszMessage_Point[75]);
		Boucle_Erreur();
	}

	return(_LECTEUR_GOOD);
} /*  */
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Status_Feed</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Determine if a card is entered</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Lecteur_Status_Feed(uchar *Port)
{
	int iResult;
	char choix, szTempo[60];

	iResult = LecteurStatusFeed(Port);

	if ( PORT_ACTIVE == _PORT_2 )
	{
		if(iResult == CARD_HOME)
		{
			SetTimer(2);
			COLOR = _ON_RED;
			Light_LED(COLOR);
			bBusy = true;
			return(_LECTEUR_GOOD);
		}
		else if(strcmp(System_Used,"JITES") != 0)/*PMD*/
		{
			if((iResult != CARD_NO) && (iResult != CARD_GATE))
			{
				/*PMD*/
				CloseConnection(Port);
				while(!Lecteur_2_Init(&gsParamMgnCdUrne))
				{
					sprintf(szTempo,"%s%s",pszMessage_Point[74],pszMessage_Point[75]);
					Lcd_Affiche(0,0, szTempo);
					Make_Noise(SOUND1);
					SetTimer(2);
				}
				Lcd_Affiche(0,0, " ");

				if(bRecCard)
				{
					Remove_Vote();
					bRecCard = false;

					Lcd_Affiche(0,0, pszMessage_Point[91]);

					return _LECTEUR_GOOD;
				}

				SetTimer(2);
			}
		}
	}
	else
	{
		if(strcmp(System_Used,"DIGIVOTE") == 0)
			Video_Affiche(SV, pszMessage_Point[31]);
		if(iResult == CARD_HOME)
		{
			if(strcmp(System_Used,"DIGIVOTE") == 0)
				Video_Affiche(SV, pszMessage_Point[50]);
			SetTimer(1);
			return(_LECTEUR_GOOD);
		}
	}

	return(_LECTEUR_BUSY);

} /* Lecteur_Status_Feed */
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Status_Write</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Check the writing status (only validator) </DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Lecteur_Status_Write(uchar *Port)
{
	int status, iReturn;

	iReturn = _LECTEUR_BUSY;

	iReturn = LecteurStatusWrite(Port, Command_R1);
	if (iReturn !=_LECTEUR_BUSY )
	{
		status = Test_Retour(Command_R1);
		switch (status)
		{
		case ACK : Lecteur_Set_Led(&PORT_1,0);
			Lcd_Affiche(1, 0, " ");
			if(MULTI_ELEC == 'P')/*PMD*/
			{
				if (Type_Multi == 'N')
				{
					if(strcmp(System_Used,"DIGIVOTE") == 0)
						Video_Affiche(VD, pszMessage_Point[93]);
					else
						Lcd_Affiche(PORT_ACTIVE, 0, pszMessage_Point[99]);
				}


				if (Type_Multi == 'S')
				{
					if(strcmp(System_Used,"DIGIVOTE") == 0)
						Video_Affiche(VD, pszMessage_Point[95]);
					else
						Lcd_Affiche(PORT_ACTIVE, 0, pszMessage_Point[101]);
				}

				Type_Multi = 'N';
				if(strcmp(System_Used,"DIGIVOTE") == 0)
					Video_Affiche(VP, pszMessage_Point[93]);
			}
			else
				Lcd_Affiche(PORT_ACTIVE, 0, pszMessage_Point[76]);

			iReturn = _LECTEUR_GOOD;
			break;

		default : Lecteur_Set_Led(&PORT_1,2);   /* red led lit */
			iReturn = status ;
			break;
		}
	}
	return(iReturn);
} /* Lecteur_Status_Write */
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Status_Eject</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Check the reader card eject status</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Lecteur_Status_Eject(uchar *Port)
{
	int status, iReturn, iRes;
	char szTempo[60];

	iReturn = _LECTEUR_BUSY;

	if ( PORT_ACTIVE == _PORT_1 )
	{
		LecteurStatusEject(Port, Command_R1);
		status = Test_Retour(Command_R1);
/* << 9.05 */
		if(status == _EJECT_CARD)
			status =_LECTEUR_GOOD;
/* 9.05 >> */
	}
	else
	{
		if(LecteurStatusEject(Port, Command_R2))
			return _LECTEUR_BUSY;

		status = Test_Retour(Command_R2);
	}

	switch (status)
	{

	case _DO_RECOMM:
		if(SENS_2 == _PASS_OUT_REAR)
			iReturn =_EJECT_CARD_REAR;
		else
			iReturn =_EJECT_CARD;
		break;

	case  _LECTEUR_GOOD :
		if ( PORT_ACTIVE == _PORT_2 )
			VAR_DEB = 0;

		iReturn = _LECTEUR_GOOD;
		break;

	case  _NON_EJECT_CARD :
		if( PORT_ACTIVE == _PORT_1 )
		{
			Lcd_Affiche(1,0, pszMessage_Point[87]);
			Make_Noise(SOUND2);
		}
		else
			Lcd_Affiche(0,0, pszMessage_Point[87]);

		iReturn = _EJECT_CARD;
		break;

	case  _CARTE_BLOCKE :
		if( PORT_ACTIVE == _PORT_2 )
		{
			Lcd_Affiche(0,0, pszMessage_Point[87]);
			status = _DO_RECOMM;
		}
		iReturn = status;
		break;

	case  _DONNEES :
		iReturn = status;
		if( PORT_ACTIVE == _PORT_2 )
			iReturn = _DO_RECOMM;

		break;

	case _TRANSMISSION_ERROR : /*PMD*/
	case _EJECT_ERREUR :
		iReturn = _TRANSMISSION_ERROR;
		break;

	default :
		if ( PORT_ACTIVE == _PORT_1  && First > 0)
		{
			if (!TimerCompare(1, _WAIT_TIME))
				Lecteur_Set_Led(&PORT_1,3);
			else
				Lecteur_Set_Led(&PORT_1,2);
		}
		First = 1;
		iReturn = status;
	}
	return(iReturn);
} /*  */
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Valide</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Intialize data format to write on the card</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Valide()
{
  Initialise_Carte(CARTE_VALID);
  Encode_Jeton(CARTE_VALID, JETON);

} /* Valide */
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Check_Election</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Check if the card comes from another polling station of the same election
		</DESCRIPTION>
        <PARAMETER>
			<NAME>pzJeton_B, pzJeton_C</NAME>
			<TYPE>char *, char *</TYPE>
			<IO>IN,IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Check_Election(char *pzJeton_B, char *pzJeton_C)
{
	char szJeton_B[4], szJeton_C[4];

	szJeton_B[0] = pzJeton_B[0];
	szJeton_B[1] = pzJeton_B[2];
	szJeton_B[2] = pzJeton_B[4];
	szJeton_B[3] = '\0';

	szJeton_C[0] = pzJeton_C[0];
	szJeton_C[1] = pzJeton_C[2];
	szJeton_C[2] = pzJeton_C[4];
	szJeton_C[3] = '\0';

	return strcmp(szJeton_B,szJeton_C);

}
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Valide</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Read a card that will be validated</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Lecteur_Valide(uchar *Port)
{
	uchar strtmp[25];
	char szBuffer[128];
	char Jeton[_JETON_MAX_BYTE+1],strtype[3];
	int status,nbcar;

	status = LecteurValide(Port, szBuffer);

	if(status != _LECTEUR_BUSY)
	{
		strcpy(Command_R1, szBuffer);
		status = Test_Retour(Command_R1);
		if((status == _EJECT_CARD) && (etat == '2'))
			return(_LECTEUR_GOOD);
		else
		{
			if(status == _EJECT_CARD)
				return(status);
		}

		Recupere_Jeton(Command_R1,Jeton);
		Calcul_Crc(Command_R1,_C_TEST_PLACE);
		Recupere_Crc(Command_R1,_C_CRC_PLACE );

		if((strcmp(JETON, Jeton) == 0) && (strcmp(Crc_Calcul, Crc_Recup) == 0))
		{
			Recupere_stat_Val(Command_R1);
			if(MULTI_ELEC == 'P')
			{
				if(Statut_Val == 'N')
					Lcd_Affiche(PORT_ACTIVE, 0, pszMessage_Point[102]);

				if(Statut_Val == 'S')
					Lcd_Affiche(PORT_ACTIVE, 0, pszMessage_Point[104]);

				if(Statut_Val == ' ')
					Lcd_Affiche(PORT_ACTIVE, 0, pszMessage_Point[77]);
			}
			else
				Lcd_Affiche(PORT_ACTIVE, 0, pszMessage_Point[77]);

			Lecteur_Set_Led(&PORT_1,1); /* green led lit */
			Make_Noise(SOUND2);
			PORT_1_NEXT_COMMAND = 4;
		}
		else if(Check_Election(JETON, Jeton) == 0)
		{
			Lcd_Affiche(PORT_ACTIVE, 0, pszMessage_Point[106]);
			Lecteur_Set_Led(&PORT_1,1); /* green led lit */
			Make_Noise(SOUND2);
			PORT_1_NEXT_COMMAND = 4;
		}

		return(_LECTEUR_GOOD);
	}
	return(_LECTEUR_BUSY);

} /* Lecteur_Valide */

/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Determine_Position</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Determine the next position where the vote contents will be save
		</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return position</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Determine_Position()
{
  if (*piNOMBRE_VOTES1 >= _E_NB_MAX_VOTE)
        return(-1);
  else
	return(*piNOMBRE_VOTES1);
} /* Determine_Position */

/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Enregistre</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Check the vote contents before to save it</DESCRIPTION>
        <PARAMETER>
			<NAME>Carte</NAME>
			<TYPE>char *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Enregistre(char *Carte, boolean bIndic)
{
  int status,iCpt,iNum, iCount, iResult;
  /*<< 9.01c*/
  unsigned int iVoteSize;
  /*>>*/
  char Jeton[_JETON_MAX_BYTE+1], szTempo[61], /*<< 9.01c*/szPassword[16]/*>>*/;
  char strtmp[4], szBuf[5];

  Recupere_Jeton(Carte, Jeton);
  Calcul_Crc(Carte,_C_TEST_PLACE);
  Recupere_Crc(Carte,_C_CRC_PLACE);

  status = strcmp(Jeton, JETON);
  Lcd_Affiche(0,0, " ");

  if((status != 0) || (strcmp(Crc_Calcul,Crc_Recup) != 0))
     {
           Lcd_Affiche(0,0, pszMessage_Point[83]);

		   if(bIndic)
		   {
				iResult = _EJECT_CARD;
				SENS_2 = _PASS_OUT_FRONT;
		   }
		   else
		   {
				iResult = EJECT_FRONT;
			    Lcd_Affiche(1,0, pszMessage_Point[14]);
				Getch(COLOR);
		   }

		   return iResult;
    }
  else
    {
      POSITION_VOTE = Determine_Position();
      if (POSITION_VOTE == -1)
        {
          Lcd_Affiche(0, 0, pszMessage_Point[22]);

		  if(bIndic)
		   {
			   Wait_Time(1);
			   iResult = _CARTE_OVERFLOW;
			   SENS_2 = _PASS_OUT_FRONT;
		   }
		   else
		   {
				iResult = EJECT_FRONT;
			    Lcd_Affiche(1,0, pszMessage_Point[14]);
				Getch(COLOR);
		   }

		   return iResult;
        }

	  if(SUPPORT != 'N')
		Lcd_Affiche(0, 0, pszMessage_Point[85]);

      Recupere_stat(Carte); /* N ou S */
      SAUVE_TO_EPROM = true;
      Recupere_Vote(Carte);
      status = Verifie_E_Vote();
      if(status != 0)
        {
           Lcd_Affiche(0,0, pszMessage_Point[83]);

		   if(bIndic)
		   {
			   iResult = _EJECT_CARD;
			   SENS_2 = _PASS_OUT_FRONT;
		   }
		   else
		   {
				iResult = EJECT_FRONT;
			    Lcd_Affiche(1,0, pszMessage_Point[14]);
				Getch(COLOR);
		   }

		   return iResult;
        }

	  SAUVE_TO_EPROM = true;
	  SENS_2 = _PASS_OUT_REAR;

	  if(SUPPORT == 'R')
	  {
		  iNum = Disk_Num() ;
		  if(iNum == 0)
		  {
			  iNum = Change_Disque(pszMessage_Point[122],false);
			  if(strcmp(System_Used,"JITES") == 0)
			  {
				Lcd_Affiche(0,0, " ");
				Lcd_Affiche(1,0, " ");
			  }
		  }
		  iDiskId = iNum;
		  /*<< 9.05*/
		  iCount = Read_Counter(bIndic);

		  /*if(bIndic)*/
		  if(bIndic || bWriteData_Ram)
		  /*>>*/
		  {
			Save_Vote();
			sprintf(szBuf,"%04d",*piNOMBRE_VOTES1);
			Write_Counter(szBuf,4);
		  }
		  else
		  {
			  if(iCount > 0)
			  {
				  iCount += 1;
				  sprintf(szBuf,"%04d",iCount);

				  /*<< 9.01c*/
				  iVoteSize = C_VOTE_MAX_BYTE + _C_CRC_MAX_BYTE + _C_TEST_MAX_BYTE;
				  Generate_Password(szPassword,iCount,true);
				  Encrypt_Decrypt(szVoteContent,szPassword,iVoteSize);
				  Encode_Data_Disk(iCount,szVoteContent,iVoteSize,'V');
				  Encode_Data_Disk(0,szBuf,4,'C');
				  /*>>*/
			  }
			  /*<< 9.01c*/
			  else if(iCount == 0)
			  {
				  sprintf(szBuf,"%04d",1);
				  iVoteSize = C_VOTE_MAX_BYTE + _C_CRC_MAX_BYTE + _C_TEST_MAX_BYTE;
				  Generate_Password(szPassword,iCount,true);
				  Encrypt_Decrypt(szVoteContent,szPassword,iVoteSize);
				  Encode_Data_Disk(iCount,szVoteContent,iVoteSize,'V');
				  Encode_Data_Disk(0,szBuf,4,'C');
			  }
			  else
			  {
				  /*switch to the mode without recording*/
				  SUPPORT = 'N';
				  bNoSupMode = true;
				  if(!bReading_Loop)
				  {
						Lcd_Affiche(0,0,pszMessage_Point[60]);
						Lcd_Affiche(1,0,pszMessage_Point[14]);
						Getch(COLOR);
				  }
			  }

			  /*Encode_Data_Disk(iCount,szVoteContent,strlen(szVoteContent),'V');
			  Encode_Data_Disk(0,szBuf,4,'C');*/
			  /*>>*/
		  }

		  SetTimer(2);
	  }

    }

  if(bIndic)
	iResult = _LECTEUR_GOOD;
  else
	iResult = EJECT_REAR;

  return iResult;
} /* Enregistre */

/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Save_Vote</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Save the vote contents in EPROM, RAM(FE_RAM) or in floppy file FE_DSK
		</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Save_Vote()
{
	char szTempo[65], szBuf[5], /*<< 9.01c*/szPassword[16]/*>>*/;
	boolean bIndic;
	/*<< 9.01c*/
	unsigned int iVoteSize;
	/*>>*/

	if ((SENS_2 == _PASS_OUT_REAR) && (SAUVE_TO_EPROM == true))
	{
       while(Table[Cmpt_Gen] != 0)
	   {
			if ( Cmpt_Gen >= (_E_NB_MAX_VOTE - 1))
				Cmpt_Gen = 0 ;
			else Cmpt_Gen += 1;
	   }
	   Table[Cmpt_Gen] = 1;

	   if((SUPPORT != 'N') && !bRecCard)
	   {
		   /*PMD*/
		   Check_Vote_Counters();
		   /*<< 9.01c*/
		   iVoteSize = C_VOTE_MAX_BYTE + _C_CRC_MAX_BYTE + _C_TEST_MAX_BYTE;
		   Generate_Password(szPassword,Cmpt_Gen,true);
		   Encrypt_Decrypt(szVoteContent,szPassword,iVoteSize);
		   /*Encode_E_Vote(Cmpt_Gen, szVoteContent,strlen(szVoteContent));*/
		   Encode_E_Vote(Cmpt_Gen, szVoteContent,iVoteSize);
		   /*>> */

		   if(SUPPORT == 'R')
				bRecCard = true;

		   if(MULTI_ELEC == 'P')
		   {
			  if(Statut_Vote == 'N')
			  {
					*piNOMBRE_NATIO_VOTES1 += 1;
					*piNOMBRE_NATIO_VOTES2 += 1;
					*piNOMBRE_NATIO_VOTES3 += 1;

					if(strcmp(System_Used,"DIGIVOTE") == 0)
					{
						sprintf(szBuf,"%04d",*piNOMBRE_NATIO_VOTES1);
						Video_Affiche(CN, szBuf);
						Video_Affiche(CNX, "X");
						Video_Affiche(CEX, " ");
					}
			  }
			  else if(Statut_Vote == 'S')
			  {
					*piNOMBRE_STR_VOTES1 += 1;
					*piNOMBRE_STR_VOTES2 += 1;
					*piNOMBRE_STR_VOTES3 += 1;

					if(strcmp(System_Used,"DIGIVOTE") == 0)
					{
						sprintf(szBuf,"%04d",*piNOMBRE_STR_VOTES1);
						Video_Affiche(CE, szBuf);
						Video_Affiche(CNX, " ");
						Video_Affiche(CEX, "X");
					}
			  }
		   }

			*piNOMBRE_VOTES1 += 1;
			*piNOMBRE_VOTES2 += 1;
			*piNOMBRE_VOTES3 += 1;

			if(strcmp(System_Used,"DIGIVOTE") == 0)
			{
				sprintf(szBuf,"%04d",*piNOMBRE_VOTES1);
				Video_Affiche(CT, szBuf);
			}

			Lcd_Affiche(0,0,pszMessage_Point[86]);

	   }
	}
}
/**************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Enregistre</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Read a card that contains a vote result</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
#pragma argsused
int Lecteur_Enregistre(uchar *Port)
{
	int status, iReturn;

	iReturn = _LECTEUR_BUSY;

	if(LecteurEnregistre(Port, Command_R2))
	{
		return(iReturn);
	}


	status = Test_Retour(Command_R2);
	switch (status)
	{
	case _DONNEES    :
		status = Enregistre(Command_R2,true);
		iReturn = status;
		break;

	case _DO_RECOMM:
		status = _EJECT_CARD;

	case _EJECT_CARD : SENS_2 = _PASS_OUT_FRONT;

		if ((PORT_ACTIVE == _PORT_2) && (etat == '2'))
		{
			COLOR =_ON_RED_GREEN;
			Light_LED(COLOR);
			Lcd_Affiche(0, 0, pszMessage_Point[79]);
		}
		iReturn = status;
		break;

	default : iReturn = status;
		break;
	}

	return(iReturn);
} /* Lecteur_Enregistre */

/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_Valide_Vote</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Check if card is ejected to front or rear. If card is ejected to rear
		the vote contents is saved (only jites system), otherwise a message error
		is displayed
		</DESCRIPTION>
        <PARAMETER>
			<NAME>Port</NAME>
			<TYPE>uchar *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION>Port indicate the active port</DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
#pragma argsused
int Lecteur_Valide_Vote(uchar *Port)
{

  int iCpt = 0;

  if((SUPPORT == 'R') && bRecCard) /*PMD*/
  {

	  while(access(szCtrlFile,0) == 0)
	  {
			remove(szCtrlFile);
			iCpt += 1;
			if(iCpt > 9)
			{
				Lcd_Affiche(0,0, pszMessage_Point[25]);
				Lcd_Affiche(1,0, pszMessage_Point[62]);
				Getch(COLOR);
				Ram_Disk_Load();
			}

	  }

	  bRecCard = false;

  }
  else if(SUPPORT == 'E')
	Save_Vote();

  /*<< 9.04*/
  /*if ((SENS_2 == _PASS_OUT_REAR) && (SAUVE_TO_EPROM == false))
  {
     Lcd_Affiche(0,0,pszMessage_Point[80]);
	 Lcd_Affiche(1,0," ");
  }*/
 /*>>*/

 SAUVE_TO_EPROM = false;
 SENS_2 = _PASS_OUT_FRONT;

 return(_LECTEUR_GOOD);
} /* Lecteur_Valide_Vote */

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

/*
   <FUNCTION>
		<NAME>Lecteur_1_Init</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Initialize the validator reader card</DESCRIPTION>
        <PARAMETER>
			<NAME>psParm</NAME>
			<TYPE>s_Parameters *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Lecteur_1_Init(s_Parameters* psParm)
{
	int status;
	char szMsgError[80];

	status = LecteurInit(&PORT_1, psParm);
	if(status < 0)
	{
		return 0;
	}
	LecteurEject(&PORT_1, EJECT_FRONT);

	return 1;
} /*  */

/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Lecteur_2_Init</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Initialize the urn reader card</DESCRIPTION>
        <PARAMETER>
			<NAME>psParm</NAME>
			<TYPE>s_Parameters *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION>return execution status</DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Lecteur_2_Init(s_Parameters* psParm)
{
	int status;

	status = LecteurInit(&PORT_2, psParm);
	if(status < 0)
	{
		return 0;
	}

	return 1;
} /* */
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>Init_CheckVote</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
		Check during the system initialization the presence of a card or temporary
		file witch makes it possible to control the recording of a vote.
		</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Init_CheckVote(char cChoice)
{
	int status, iRes, iCount;
	char szLVote[76], szTempo[90], choix, szBuf[5];
	boolean bIndic = true;

	if(strcmp(System_Used,"DIGIVOTE") == 0)
	{
		SENS_2 = EJECT_FRONT;

		if((cChoice == '1') && (access(Chemin_D, 0) == 0))
		{
			/*<< 9.01c*/
			bWriteData_Ram = false;
			/*>>*/
			LecteurRead(&PORT_2);
			LecteurEnregistre(&PORT_2, Command_R2);

			status = Test_Retour(Command_R2);
			if(status == _DONNEES)
			{
				/*<< 9.01c*/
				Recupere_Nb_Cartes();
				/*>>*/
				/*Check if card not ejects rear*/
				if(access(szCtrlFile,0) == 0)
				{
					iRes = Read_Vote(szLVote);
					if(iRes == -1)
					{
						/*switch to the mode without recording
							if vote cannot be removed*/
						SUPPORT = 'N';
						bNoSupMode = true;
						Lcd_Affiche(0,0,pszMessage_Point[60]);
						Lcd_Affiche(1,0,pszMessage_Point[14]);
						Getch(COLOR);
					}
					else
					{
						Recupere_Vote(Command_R2);
						status = strcmp(szLVote,szVoteContent);
						if(iRes == 0)
							SENS_2 = Enregistre(Command_R2,false);
						else if((iRes == 1) && (status == 0))
							SENS_2 = EJECT_REAR;

					}

					remove(szCtrlFile);
				}
				else
					SENS_2 = Enregistre(Command_R2,false);
			}
			else if(status == _EJECT_CARD)
			{
				Lcd_Affiche(0, 0, pszMessage_Point[30]);
				Lcd_Affiche(1,0,pszMessage_Point[14]);
				Getch(COLOR);
			}
			else if(access(szCtrlFile,0) == 0)
			{
				GetVersionCommande(&PORT_2, szTempo);

				if(strcmp(szTempo,"UNKNOWN VERSION") != 0)
				{
					iRes = Lecteur_CardPosition(&PORT_2);/*PMD*/
					if(iRes == CARD_GATE)
					{
						/*remove vote into file FE_DSK*/
						bIndic = Cancel_Vote();

						Lcd_Affiche(0,0,"");
						Lcd_Affiche(1,0,"");

						if(bIndic)
						{
							iCount = Read_Counter(false);
							if(iCount > 0)
							{
								iCount -= 1;
								sprintf(szBuf,"%04d",iCount);
								Encode_Data_Disk(0,szBuf,4,'C');
							}
							/*<< 9.01c*/
							else if(iCount == -1)
							{
								/*switch to the mode without recording*/
								SUPPORT = 'N';
								bNoSupMode = true;
								Lcd_Affiche(0,0,pszMessage_Point[60]);
								Lcd_Affiche(1,0,pszMessage_Point[14]);
								Getch(COLOR);
							}
							/*>>*/
						}
						else
						{
							/*switch to the mode without recording
								if vote cannot be removed*/
							SUPPORT = 'N';
							bNoSupMode = true;
							Lcd_Affiche(0,0,pszMessage_Point[60]);
							Lcd_Affiche(1,0,pszMessage_Point[14]);
							Getch(COLOR);
						}
					}
				}

				remove(szCtrlFile);
			}
		}

		LecteurEject(&PORT_2, SENS_2);
	}

}
/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Display_Votes_Counters</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Display vote counters</DESCRIPTION>
        <PARAMETER>
			<NAME>pusCount, usLine</NAME>
			<TYPE>unsigned short *, unsigned short</TYPE>
			<IO>IN,IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Display_Votes_Counters(unsigned short *pusCount, unsigned short usLine)
{
    /* << 9.03*/
	/*char strtemp[21];*/
	char strtemp[25];
	/* >> */

    Lcd_Affiche(0, 0, "");
    Lcd_Affiche(1, 0, "");

    if(MULTI_ELEC == 'N')
    {

		if((*piNOMBRE_VOTES1 == *piNOMBRE_VOTES2) && (*piNOMBRE_VOTES2 == *piNOMBRE_VOTES3))
		{
			if(*piNOMBRE_VOTES1 > 1)
			sprintf(strtemp,pszMessage_Point[88] , *piNOMBRE_VOTES1);
			else
			sprintf(strtemp,pszMessage_Point[110] , *piNOMBRE_VOTES1);

			Lcd_Affiche(usLine, 0, strtemp);
		}
		else
			 Lcd_Affiche(usLine, 0, pszMessage_Point[120]);

    }
	else if (GLOBAL_STR == 1)
    {
		switch(*pusCount)
		{
	    case 1 :
		     if((*piNOMBRE_NATIO_VOTES1 == *piNOMBRE_NATIO_VOTES2) &&
			(*piNOMBRE_NATIO_VOTES2 == *piNOMBRE_NATIO_VOTES3))
		     {
			 if(*piNOMBRE_NATIO_VOTES1 > 1)
			      sprintf(strtemp,pszMessage_Point[96] , *piNOMBRE_NATIO_VOTES1);
			 else
			      sprintf(strtemp,pszMessage_Point[111] , *piNOMBRE_NATIO_VOTES1);

			 Lcd_Affiche(usLine, 0, strtemp);
			 *pusCount += 1;
		     }
		     else Lcd_Affiche(usLine, 0, pszMessage_Point[120]);

		     break;

	    case 2 :
		     if((*piNOMBRE_STR_VOTES1 == *piNOMBRE_STR_VOTES2) &&
			(*piNOMBRE_STR_VOTES2 == *piNOMBRE_STR_VOTES3))
		     {
			 if(*piNOMBRE_STR_VOTES1 > 1)
			      sprintf(strtemp,pszMessage_Point[98] , *piNOMBRE_STR_VOTES1);
			 else
			      sprintf(strtemp,pszMessage_Point[113] , *piNOMBRE_STR_VOTES1);

			 Lcd_Affiche(usLine, 0, strtemp);
			 *pusCount += 1;
		     }
		     else Lcd_Affiche(usLine, 0, pszMessage_Point[120]);

		     break;

	    case 3 :
		     if((*piNOMBRE_VOTES1 == *piNOMBRE_VOTES2) && (*piNOMBRE_VOTES2 == *piNOMBRE_VOTES3))
		     {
			 if(*piNOMBRE_VOTES1 > 1)
			     sprintf(strtemp,pszMessage_Point[88] , *piNOMBRE_VOTES1);
			 else
			     sprintf(strtemp,pszMessage_Point[110] , *piNOMBRE_VOTES1);

			 Lcd_Affiche(usLine, 0, strtemp);
			 *pusCount = 1;
		     }
		     else
			 Lcd_Affiche(usLine, 0, pszMessage_Point[120]);

		     break;
		}
    }

}
/*******************************************************************************************/
/*
   <FUNCTION>
		<NAME>Remove_Vote</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>
			Use after a transmission error with the reader card of the ballot box.
			Check the presence of the card in the reader card. Read the temporary file
			if it exists and compares the contents of the vote with that located at the
			same position in file FE_DSK. If the contents of the vote are identical, the vote
			is recovered or removed on file FE_DSK
		</DESCRIPTION>
        <PARAMETER>
			<NAME></NAME>
			<TYPE></TYPE>
			<IO></IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Remove_Vote()
{
	boolean bIndic;
	char szMsgError[80], szBuffer[76], szBuf[5], szTempo[90];
	sRecVote Buffer;
	int iRes, iHandle, status, iReturn;

	iReturn = _LECTEUR_GOOD;

	if(SUPPORT == 'R')
	{
		SENS_2 = EJECT_FRONT;

		LecteurRead(&PORT_2);
		LecteurEnregistre(&PORT_2, Command_R2);

		status = Test_Retour(Command_R2);
		if(status == _DONNEES)
		{
			/*<< 9.01c*/
			bWriteData_Ram = true;
			/*>>*/
			/*Check if card not ejects rear*/
			if(access(szCtrlFile,0) == 0)
			{
				iRes = Read_Vote(szBuffer);
				if(iRes == -1)
				{
					/*switch to the mode without recording*/
					SUPPORT = 'N';
					bNoSupMode = true;
				}
				else
				{
					Recupere_Vote(Command_R2);
					status = strcmp(szBuffer,szVoteContent);
					if(iRes == 0)
					{
						SENS_2 = Enregistre(Command_R2,false);
						if((SENS_2 == EJECT_REAR) && (SUPPORT != 'N'))
						{
							Disk_Ram_Load();
							Recupere_Nb_Cartes();
							if(MULTI_ELEC == 'P')
							{
								sprintf(szBuf,"%04d",*piNOMBRE_NATIO_VOTES1);
								Video_Affiche(CN, szBuf);
								sprintf(szBuf,"%04d",*piNOMBRE_STR_VOTES1);
								Video_Affiche(CE, szBuf);
							}
							sprintf(szBuf,"%04d",*piNOMBRE_VOTES1);
							Video_Affiche(CT, szBuf);
						}
					}
					else if((iRes == 1) && (status == 0))
						SENS_2 = EJECT_REAR;

				}

				remove(szCtrlFile);
			}
			else
			{
				SENS_2 = Enregistre(Command_R2,false);
				if((SENS_2 == EJECT_REAR) && (SUPPORT != 'N'))
				{
					Disk_Ram_Load();
					Recupere_Nb_Cartes();
					if(MULTI_ELEC == 'P')
					{
						sprintf(szBuf,"%04d",*piNOMBRE_NATIO_VOTES1);
						Video_Affiche(CN, szBuf);
						sprintf(szBuf,"%04d",*piNOMBRE_STR_VOTES1);
						Video_Affiche(CE, szBuf);
					}
					sprintf(szBuf,"%04d",*piNOMBRE_VOTES1);
					Video_Affiche(CT, szBuf);
				}
			}

		}
		else if(access(szCtrlFile,0) == 0)
		{
			GetVersionCommande(&PORT_2, szTempo);

			if(strcmp(szTempo,"UNKNOWN VERSION") != 0)
			{
			   /*<< 9.01c*/
				/*iHandle = open(szCtrlFile, O_RDONLY | O_BINARY);
				if (iHandle == -1)
				{
					sprintf(szMsgError,"Error opening file %s in Remove_Vote function.\nFile source %s\n",szCtrlFile, __FILE__);
					Erreur(szMsgError);
					//switch to the mode without recording
					SUPPORT = 'N';
					bNoSupMode = true;
				}
				else
				{
					iRes = read(iHandle,&Buffer,sizeof(Buffer));
					if(iRes == -1)
					{
						sprintf(szMsgError,"Error reading from the file %s in Remove_Vote function.\nFile source %s\n",szCtrlFile, __FILE__);
						Erreur(szMsgError);
						//switch to the mode without recording
						SUPPORT = 'N';
						bNoSupMode = true;
					}
					close(iHandle);
				}*/

				/*remove vote into files FE_DSK and FE_RAM*/
				//iRes = Check_vote(Buffer.szContent);
				iRes = Check_vote();
				/*>>*/
				if((iRes == 1) || (iRes == 2))
				{
					Recupere_Nb_Cartes();
					sprintf(szBuf,"%04d",*piNOMBRE_VOTES1);
					Write_Counter(szBuf,4);

					if(MULTI_ELEC == 'P')
					{
						sprintf(szBuf,"%04d",*piNOMBRE_NATIO_VOTES1);
						Video_Affiche(CN, szBuf);
						sprintf(szBuf,"%04d",*piNOMBRE_STR_VOTES1);
						Video_Affiche(CE, szBuf);
					}
					sprintf(szBuf,"%04d",*piNOMBRE_VOTES1);
					Video_Affiche(CT, szBuf);
				}
				else if((iRes == -1) || (iRes == -2))
				{
					/*switch to the mode without recording
						if vote cannot be removed*/
					SUPPORT = 'N';
					bNoSupMode = true;
				}
			}

			remove(szCtrlFile);
		}

		LecteurEject(&PORT_2, SENS_2);

		/*<< 9.01c*/
		bWriteData_Ram = false;
		/*>>*/
	}

	return iReturn;
}
/****************************************************************************/
/*
   <FUNCTION>
		<NAME>LoopValidator</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Validator instructions carried out in the reading loop</DESCRIPTION>
	<PARAMETER>
			<NAME>ucPcType, iRecount</NAME>
			<TYPE>uchar, int</TYPE>
			<IO>IN,IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void LoopValidator(uchar ucPcType, boolean bRecount)
{
	int MEddDebug = 1;

	int Status_1;

	if (PORT_1_DO_NEXT_SEND)
	{
		Status_1 = Do_command(PORT_1_NEXT_COMMAND, &PORT_1);
		if(!bRecount)
		{
			switch (Status_1)
			{
			case _DO_CLEAR:
				PORT_1_NEXT_COMMAND = _DEBUT;
				PORT_1_DO_NEXT_SEND = true;
				SENS_1 = _PASS_OUT_FRONT;
				break;

			case _CARTE_BLOCKE:
			case _DO_RECOMM:
				PORT_1_NEXT_COMMAND = 1;
				PORT_1_DO_NEXT_SEND = true;
				SENS_1 = _PASS_OUT_FRONT;
				break;

			case _LECTEUR_BUSY:
				break;

			case _INVALID_CARD :
				Lcd_Affiche(1, 0, pszMessage_Point[81]);
				Make_Noise(SOUND2);

				Lecteur_Set_Led(&PORT_1,2);   /* red led lit */
				PORT_1_NEXT_COMMAND = 5;
				PORT_1_DO_NEXT_SEND = true;
				SENS_1 = _PASS_OUT_FRONT;
				break;

			case _EJECT_CARD :
				Lcd_Affiche(1, 0, pszMessage_Point[79]);
				Make_Noise(SOUND2);

				Lecteur_Set_Led(&PORT_1,2);   /* red led lit */
				PORT_1_NEXT_COMMAND = 5;
				PORT_1_DO_NEXT_SEND = true;
				SENS_1 = _PASS_OUT_FRONT;
				break;
			default:
				PORT_1_NEXT_COMMAND++;
				PORT_1_DO_NEXT_SEND = true;
			}
		}
		else
		{
			Lecteur_Set_Led(&PORT_1,2);   /* red led lit*/
            		PORT_1_NEXT_COMMAND = 5;
            		PORT_1_DO_NEXT_SEND = true;
			SENS_1 = _PASS_OUT_FRONT;
		}
	}

	if (!TimerCompare(1, _WAIT_TIME) && MEddDebug == 1)
		if(PORT_1_NEXT_COMMAND > _DEBUT)
		{
			Lecteur_Set_Led(&PORT_1,3);
			PORT_1_NEXT_COMMAND = 5;
			PORT_1_DO_NEXT_SEND = true;
			SENS_1 = _PASS_OUT_FRONT;
			SetTimer(1);
		}

}
/********************************************************************/
/*
   <FUNCTION>
		<NAME>LoopUrne</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Urn instructions carried out in the reading loop</DESCRIPTION>
        <PARAMETER>
			<NAME>ucPcType</NAME>
			<TYPE>uchar</TYPE>
			<IO>IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
#pragma argsused
void LoopUrne(uchar ucPcType)
{
	int MEddDebug = 1;
	int Status_2;
	char szTempo[60];

	CheckQueue(&PORT_2);

	if(PORT_2_DO_NEXT_SEND)
	{

		Status_2 = Do_command(PORT_2_NEXT_COMMAND, &PORT_2);

		switch(Status_2)
		{
		case _DO_CLEAR:
			PORT_2_NEXT_COMMAND = 8;
			PORT_2_DO_NEXT_SEND = true;
			SENS_2 = _PASS_OUT_FRONT;
			break;

		case _DO_RECOMM:
			PORT_2_NEXT_COMMAND = 1;
			PORT_2_DO_NEXT_SEND = true;
			SENS_2 = _PASS_OUT_FRONT;
			break;

		case _CARTE_OVERFLOW:
			PORT_2_NEXT_COMMAND = 3;
			SENS_2 = _PASS_OUT_FRONT;
			PORT_2_DO_NEXT_SEND = true;
			break;

		case _CARTE_BLOCKE:
			PORT_2_NEXT_COMMAND = 9;
			SENS_2 = _PASS_OUT_FRONT;
			PORT_2_DO_NEXT_SEND = true;
			break;


		case _INVALID_CARD:
			Lcd_Affiche(0, 0, pszMessage_Point[81]);

			PORT_2_NEXT_COMMAND = 3;
			PORT_2_DO_NEXT_SEND = true;
			SENS_2 = _PASS_OUT_FRONT;
			break;

		case _TRANSMISSION_ERROR :
		case _EJECT_ERREUR :

			PORT_2_NEXT_COMMAND = _DEBUT;
			PORT_2_DO_NEXT_SEND = true;
			SetTimer(2);/*PMD*/
			break;

		case _EJECT_CARD :
			PORT_2_NEXT_COMMAND = 3;
			SENS_2 = _PASS_OUT_FRONT;
			PORT_2_DO_NEXT_SEND = true;
			break;

		case _EJECT_CARD_REAR :
			PORT_2_NEXT_COMMAND = 3;
			SENS_2 = _PASS_OUT_REAR;
			/* << 9.04*/
			/*SAUVE_TO_EPROM = false;*/
			/* >>*/
			PORT_2_DO_NEXT_SEND = true;
			VAR_DEB = 0;
			break;

		default :
			if(ucPcType == DIVIGOTE)
			{
				if(Status_2 == NO_ACTION)
				{
					PORT_2_NEXT_COMMAND = 8;
					break;
				}
			}
			if(Status_2 != _LECTEUR_BUSY)
			{
				PORT_2_NEXT_COMMAND++;
				PORT_2_DO_NEXT_SEND = true;
			}
		}
	}

	if (!TimerCompare(2, _WAIT_TIME) && MEddDebug == 1)
		if(PORT_2_NEXT_COMMAND > _DEBUT)
		{
			CloseConnection(&PORT_2);/*PMD*/
			if(strcmp(System_Used,"JITES") != 0)
			{
				if(Lecteur_2_Init(&gsParamMgnCdUrne))
				{
					LecteurEject(&PORT_2, EJECT_FRONT);
					PORT_2_NEXT_COMMAND = 1;
				}
				else
				{
					sprintf(szTempo,"%s%s",pszMessage_Point[74],pszMessage_Point[75]);
					Lcd_Affiche(0,0, szTempo);
					Make_Noise(SOUND1);
					PORT_2_NEXT_COMMAND = _DEBUT;
				}
			}
			else
			{
				Lecteur_2_Init(&gsParamMgnCdUrne);
				_WAIT;
				PORT_2_NEXT_COMMAND = 1;
			}

			PORT_2_DO_NEXT_SEND = true;
			SetTimer(2);
		}


}

/**********************************************************************/
/*
   <FUNCTION>
		<NAME>Handler_Keyb</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Keyboard instructions carried out in the reading loop</DESCRIPTION>
        <PARAMETER>
			<NAME>cValue, pusCount_Vote, pbIndic</NAME>
			<TYPE>char, unsigned short *, boolean *</TYPE>
			<IO>IN,INOUT,INOUT</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Handler_Keyb(char cValue, unsigned short *pusCount_Vote)
{
	char sztmp[41];

	switch(cValue)
    {
       case 0x20 : /*space-blank*/
	   case 0x0D : /*carriage return*/
		  if((strcmp(System_Used,"JITES") != 0) && (MULTI_ELEC == 'P'))
		  {
			  if(Type_Multi == 'N')
			  {
				if((GLOBAL_STR == 1)&&(PORT_1_NEXT_COMMAND == _DEBUT))
				{
					Type_Multi = 'S';
					Valide();
					if(strcmp(System_Used,"DIGIVOTE") == 0)
						Video_Affiche(VP, pszMessage_Point[95]);
					putch(0x07);
				}
			  }
			  else
			  {
				if(PORT_1_NEXT_COMMAND == _DEBUT)
				{
					Type_Multi = 'N';
					Valide();
					if(strcmp(System_Used,"DIGIVOTE") == 0)
						Video_Affiche(VP, pszMessage_Point[93]);
					putch(0x07);
				}
			  }
		  }
        break;

	  case 0x31 : /*1*/
		  if(strcmp(System_Used,"JITES") == 0)
				Lcd_Affiche(0, 0, _Version);
	      break;

	  case 0x32 : /*2*/
	  case 0x43 : /*C*/
	  case 0x53 : /*S*/
		  if(bRecount_Mode)
			PORT_1_NEXT_COMMAND = _DEBUT;
		  if((PORT_1_NEXT_COMMAND == _DEBUT )
                     && (PORT_2_NEXT_COMMAND == _DEBUT ))
                                  DEMANDE_FERMETURE = true;
          break;

	  case 0x35 : /*5*/
		  if(strcmp(System_Used,"JITES") == 0)
		  {
			  if (SUPPORT == 'N')
			  {
				Lcd_Affiche(0,0,pszMessage_Point[60]);
				Lcd_Affiche(1,0,pszMessage_Point[63]);
			  }
			  else
			  {
				Check_Vote_Counters();
				Display_Votes_Counters(pusCount_Vote,0);
			  }
			  _WAITL;
		  }
	      break;

	  case 0x36 : /*6*/
		  if((strcmp(System_Used,"JITES") == 0) && (MULTI_ELEC == 'P'))
		  {
			  if((GLOBAL_STR == 1)&&(PORT_1_NEXT_COMMAND == _DEBUT))
			  {
				 Type_Multi = 'S';
				 Valide();
				 Lcd_Affiche(1, 0, " ");
				 Lcd_Affiche(1, 0, pszMessage_Point[95]);
				 if(strcmp(System_Used,"DIGIVOTE") == 0)
					Video_Affiche(VP, pszMessage_Point[95]);
				 putch(0x07);

				 *pusCount_Vote = 1;
			  }
		  }
          break;

	  case 0x37 : /*7*/
		  if((strcmp(System_Used,"JITES") == 0) && (MULTI_ELEC == 'P'))
		  {
			  if(PORT_1_NEXT_COMMAND == _DEBUT)
			  {
				 Type_Multi = 'N';
				 Valide();
				 Lcd_Affiche(1, 0, " ");
				 Lcd_Affiche(1, 0, pszMessage_Point[93]);
				 if(strcmp(System_Used,"DIGIVOTE") == 0)
					Video_Affiche(VP, pszMessage_Point[93]);
				 putch(0x07);

				 *pusCount_Vote = 1;
			  }
		  }
	      break;

	  case 0x38 : /*8*/
		  if(strcmp(System_Used,"JITES") == 0)
		  {
			  strcpy(sztmp,JETON_ETENDU);
			  Lcd_Affiche(0, 0, pszMessage_Point[119]);
			  Lcd_Affiche(1, 0, sztmp);

			  *pusCount_Vote = 1;
		  }
	      break;
    }
}
/**********************************************************************/
/*
   <FUNCTION>
		<NAME>Boucle_Lecteur</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Reading loop</DESCRIPTION>
        <PARAMETER>
			<NAME>psPcType</NAME>
			<TYPE>s_PcType *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
#pragma argsused
void Boucle_Lecteur(s_PcType* psPcType)
{
   int Status, iNum;
   char Klavier, szTempo[65], szBuf[5];
   unsigned short usCptVote = 1;
   uchar ucPcType;

	if(psPcType->iPcType >= URNE_DIGIVOTE_1 && psPcType->iPcType <= URNE_DIGIVOTE_2)
		ucPcType = DIVIGOTE;
	else
		ucPcType = JITES;

   rang = 0;
   bRecCard = false;
   bBusy = false;

   Type_Multi = 'N';
   Valide();

   SECU = 0;

   PORT_1_NEXT_COMMAND = 5;
   PORT_1_DO_NEXT_SEND = true;
   PORT_2_NEXT_COMMAND = 6;
   PORT_2_DO_NEXT_SEND = true;
   SENS_1 = _PASS_OUT_FRONT;
   SENS_2 = _PASS_OUT_FRONT;
   /*<< 9.04*/
   /*SetTimer(1);
   SetTimer(2);*/
   /*>>*/
   First = 0;
   DEMANDE_FERMETURE = false;
   bReading_Loop = true;

   if(SUPPORT != 'N')
   {
	   /*<< 9.01c*/
	   /*if(SUPPORT == 'R')*/
	   if((SUPPORT == 'R') && bStart)
	   /*>>*/
	   {
		   iNum = Disk_Num();
		   while(iNum != iDiskId)
		   {
				sprintf(szTempo,pszMessage_Point[114],iDiskId);
				iNum = Change_Disque(szTempo,true);
		   }
	   }

	   /*<< 9.01c*/
	   if(bStart)
	   /* >>  */
			Recupere_Nb_Cartes();

	   Cmpt_Gen = *piNOMBRE_VOTES1;

	   if(strcmp(System_Used,"DIGIVOTE") == 0)
	   {
		   if(MULTI_ELEC == 'P')
		   {
			   sprintf(szBuf,"%04d",*piNOMBRE_NATIO_VOTES1);
			   Video_Affiche(CN, szBuf);
			   sprintf(szBuf,"%04d",*piNOMBRE_STR_VOTES1);
			   Video_Affiche(CE, szBuf);
		   }
		   sprintf(szBuf,"%04d",*piNOMBRE_VOTES1);
		   Video_Affiche(CT, szBuf);
	   }
   }

   if(bStart)
	   Lcd_Affiche (0, 0, pszMessage_Point[91]);
   else
   {
	   /*<< 9.02a*/
	   /*Lcd_Affiche (0, 0, pszMessage_Point[16]);*/
	   if(strcmp(System_Used,"JITES") == 0)
	   {
		   Lcd_Affiche (0, 0, pszMessage_Point[15]);
		   Lcd_Affiche (1, 0, pszMessage_Point[16]);
		   Wait_Time(3);
		   Lcd_Affiche (0, 0, " ");
		   Lcd_Affiche (1, 0, " ");
	   }
	   else
	   {
			sprintf(szTempo,"%s %s",pszMessage_Point[15],pszMessage_Point[16]);
			Lcd_Affiche (0, 0, szTempo);
			Wait_Time(3);
			Lcd_Affiche (0, 0, " ");
	   }
	   /*>>*/
   }

   if(!bRecount_Mode && (MULTI_ELEC == 'P'))
   {
		if(strcmp(System_Used,"DIGIVOTE") == 0)
			Video_Affiche(VP, pszMessage_Point[93]);
		else
			Lcd_Affiche (1, 0, pszMessage_Point[93]);
   }

   putch(0x07);
   /*<< 9.04*/
   SetTimer(1);
   SetTimer(2);
   /*>>*/

   while (!DEMANDE_FERMETURE)
   {

		Secu_Stat();

		if(SUPPORT != 'N')
		{
			if (Cmpt_Gen >= (_E_NB_MAX_VOTE - 1))
				Cmpt_Gen = 0 ;
			else Cmpt_Gen += 1;
		}
		else if(bNoSupMode)
		{
			*piNOMBRE_NATIO_VOTES1 = 0;
			*piNOMBRE_NATIO_VOTES2 = 0;
			*piNOMBRE_NATIO_VOTES3 = 0;

			*piNOMBRE_STR_VOTES1 = 0;
			*piNOMBRE_STR_VOTES2 = 0;
			*piNOMBRE_STR_VOTES3 = 0;

			*piNOMBRE_VOTES1 = 0;
			*piNOMBRE_VOTES2 = 0;
			*piNOMBRE_VOTES3 = 0;

			if(strcmp(System_Used,"DIGIVOTE") == 0)
			{

				if(MULTI_ELEC == 'P')
				{
					sprintf(szBuf,"%04d",*piNOMBRE_STR_VOTES1);
					Video_Affiche(CN, szBuf);
					sprintf(szBuf,"%04d",*piNOMBRE_STR_VOTES1);
					Video_Affiche(CE, szBuf);
					Video_Affiche(CNX, " ");
					Video_Affiche(CEX, " ");
				}
				sprintf(szBuf,"%04d",*piNOMBRE_VOTES1);
				Video_Affiche(CT, szBuf);

				sprintf(szTempo,"%s - %s",pszMessage_Point[60],pszMessage_Point[63]);
				Video_Affiche(OG,szTempo);
			}
			else
			{
				Lcd_Affiche(0,0,pszMessage_Point[60]);
				Lcd_Affiche(1,0,pszMessage_Point[63]);
			}

			bNoSupMode = false;
		}

		LoopUrne(ucPcType);
		LoopValidator(ucPcType,bRecount_Mode);

		Klavier = Kbhit(COLOR,0);
		Handler_Keyb(Klavier, &usCptVote);
   }
} /* Boucle_Lecteur */

/***************************************************************************/
/*
   <FUNCTION>
		<NAME>Test_Retour</NAME>
	<TYPE>LOCAL</TYPE>
		<DESCRIPTION>Determine the return value associated with a command </DESCRIPTION>
	<PARAMETER>
			<NAME>Command_Rx</NAME>
			<TYPE>char *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE>int</TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
int Test_Retour(char *Command_Rx)
{
	int status;
	uchar Command_Tmp[100];

	if (*Command_Rx != 'x')
		return(_DONNEES);
	if (*(Command_Rx + 1) != '0')
		return(_DO_RECOMM); /* X8n */

	etat = *(Command_Rx + 2);
	switch(etat)
	{
	case '0' : status = _LECTEUR_GOOD;              /*  ACK   */
		break;
	case '1' : status = _DO_RECOMM;  /* X01 EJECT Error         */
		if ( PORT_ACTIVE == _PORT_2 )
		{

			CloseConnection(&PORT_2);
			Lecteur_2_Init(&gsParamMgnCdUrne);
			if(strcmp(System_Used,"DIGIVOTE") == 0)
				LecteurEject(&PORT_2, EJECT_FRONT);
			else
				_WAIT;
		}
		break;
	case '6' : status = _CARTE_BLOCKE;
		break;
	case '7' : status = _DO_RECOMM;
		break;
	case '8' : status = _DO_CLEAR;        /*     FREE READER   */
		break;
	case 'a' : status = _NON_EJECT_CARD;  /*  EJECT Error         */
		break;
	case 'b' : status =  _CARTE_BLOCKE;  /*  EJECT Error         */
		if ( PORT_ACTIVE == _PORT_2 )
		{
            CloseConnection(&PORT_2);
			Lecteur_2_Init(&gsParamMgnCdUrne);
			if(strcmp(System_Used,"DIGIVOTE") == 0)
				LecteurEject(&PORT_2, EJECT_FRONT);
		}
		break;
	case 'c' : status =  _CARTE_BLOCKE;  /*  EJECT Error         */
		break;
	case 'd' : status = _TRANSMISSION_ERROR;/*PMD*/
		break;
	case 'e': status = _EJECT_ERREUR;/*PMD*/
		break;
	default  : status = _EJECT_CARD;  /*     All other cases are ejected   */
		break;
	}
	return(status);

}
/*******************************************************************/
/*
   <FUNCTION>
		<NAME>Secu_Stat</NAME>
        <TYPE>LOCAL</TYPE>
		<DESCRIPTION>Check if system is under batteries</DESCRIPTION>
        <PARAMETER>
			<NAME>Command_Rx</NAME>
			<TYPE>char *</TYPE>
			<IO>IN</IO>
			<DESCRIPTION></DESCRIPTION>
		</PARAMETER>
		<RETURN>
			<TYPE></TYPE>
			<DESCRIPTION></DESCRIPTION>
		</RETURN>
   </FUNCTION>
*/
void Secu_Stat()
{
   char strtmp[21], c;
   int tmp;

   c = ReadBatteryState();
   if((c & 0x20) == 0x20)
           {
              if(SECU == 0)
                 {
                   SECU_TIMER = CurrentTime();
                   SECU = 1;
                 }
              else
                 {
                    if((CurrentTime() - SECU_TIMER) > 1200)
                                            SECU = 2;
                    else
                       {
			  Lcd_Affiche(0,0,pszMessage_Point[24]);
                          tmp = 15 - (( CurrentTime() - SECU_TIMER ) /  19);
                          if (tmp <= 0)
                              {
                                tmp = 0;
                                SECU = 2;
                                if ((PORT_1_NEXT_COMMAND == _DEBUT )
                                     && (PORT_2_NEXT_COMMAND == _DEBUT ))
                                                             Battery_Off();
                              }

			   sprintf(strtmp, pszMessage_Point[89], tmp);
                           Lcd_Affiche(1, 0, strtmp);
                           putch(0x07);
                       }
                  }
           }
   else
      {
        if(SECU > 0)
          {
	    Lcd_Affiche (0, 0, pszMessage_Point[91]);
	    Lcd_Affiche (1, 0, pszMessage_Point[92]);
          }
        SECU  = 0;
      }
} /* */

/*******************************************************************/
/* End of the module LECTEUR.C                                     */
/*******************************************************************/
