/******************************************************************************
*                                                                             *
*              Copyright (C),  Philips Semiconductors SLH                     *
*                                                                             *
*  All rights are reserved. Reproduction in whole or in part is prohibited    *
*           without the written consent of the copyright owner.               *
*                                                                             *
*  Philips reserves the right to make changes without notice at any time.     *
* Philips makes no warranty, expressed, implied or statutory, including but   *
* not limited to any implied warranty of merchantibility or fitness for any   *
*   particular purpose, or that the use will not infringe any third party     *
* patent, copyright or trademark. Philips must not be liable for any loss or  *
*                      damage arising from its use.                           *
*                                                                             *
*******************************************************************************
*                                                                             *
*       Project: 336355/105 - Control SW Library for HTRC110/HTRC120/HITAG2   *
*       File: 	TEST.C                                                         *
*       Authors:  St. de Zeeuw, F. Boeh                                       *
*                                                                             *
*******************************************************************************
/* Example test programm for control SW library */
/* (Configurable for PASSWORD and CRYPTO mode)  */


/* Uncomment one of the definitions below: */
//#define TEST_MODE CRYPTO
#define TEST_MODE PASSWORD


#include "htrc110.h"
#include "hitag2.h"
#include "htrc120.h"
#include <string.h>




UBYTE code ident      [4]={0xE6, 0x41, 0x00, 0x10};  /* Expected transponder identifier (to be adapted) */
UBYTE code auth       [6]={0x4D, 0x49, 0x4B, 0x52, 0x4F, 0x4E}; /* Authenticator */
UBYTE code rwd_pass   [4]={0x4D, 0x49, 0x4B, 0x52};  /* Factory default reader password */
UBYTE code transp_pass[3]={0xAA, 0x48, 0x54};        /* Factory default transponder password */
UBYTE code data_block [4]={0x12, 0x34, 0x56, 0x78};  /* Page to be written */

UBYTE idata cmd[4];                                  /* buffer for command to send */
UBYTE idata receipt[2];                              /* buffer for receipt from transponder */
UBYTE idata send_block[4];                           /* Page buffer for WRITE_PAGE command */
UBYTE idata receive_block[4];                        /* buffer for received page from transponder */
UBYTE idata version_block[32];                       /* Buffer for "GetVersion" command */

UBYTE idata cmd_backup[2];                           /* Command verification buffer */
UBYTE idata send_block_backup[4];                    /* Page verification buffer */

BOOL error;




void Callback()
{
   if( Decoder_Error() ) goto error_exit;

   switch (Protocol_State)
   {

      case P_RECEIVE_WRITE_RECEIPT:
      case P_RECEIVE_HALT_RECEIPT:
         
         /* Where to store the receipt (10 bits): */
         Set_Memory_Address(receipt);
         return;


       case P_RECEIVE_IDENT:
       case P_RECEIVE_PAGE:
       case P_RECEIVE_PASSWORD:

         /* Where to store the block (32 bits): */
         Set_Memory_Address(receive_block);
         return;


      case P_SEND_PASSWORD:


//         /* Verify identifier */
//         if( memcmp(ident, receive_block, 4) ) goto error_exit;

         /* Set password to transmit (Password mode only) */
         if(Cypher==PASSWORD)
            memcpy(send_block, rwd_pass, 4);

         Set_Memory_Address(send_block);

         return;


      case P_SEND_PAGE:

         /* Verify SEND_PAGE receipt */
         cmd_backup[1] &= 0xC0; /* mask out unused bits of command */
         if( memcmp(cmd_backup, receipt, 2) ) goto error_exit;

         /* Set page to transmit */
         Set_Memory_Address(send_block);
         return;


      case P_STOP:

         switch(HT_Command)
         {

            case HT_HALT:

               /* Verify HALT receipt */
               cmd_backup[1] &= 0xC0; /* mask out unused bits of command */
               if( memcmp(cmd_backup, receipt, 2) ) goto error_exit;
               return;

            case HT_AUTHENT:

               /* Verify transponder password */
#ifndef ENABLE_PWD_CHECK
               if( memcmp(transp_pass, receive_block+1, 3) ) goto error_exit;
#endif
               return;


            case HT_READ:

               /* Verify received block */
               if( memcmp(send_block_backup, receive_block, 4) ) goto error_exit;
               return;
         }
         return;

   }
   return;

error_exit:
   error=1;
   Protocol_Stop();
   return;
}




void restart_transponder(void)
{
   short delay;

   SET_CONFIG_PAGE(CF_PAGE_1+TXDIS);    /* switch off HTRC110 drivers/RF-field */

   for(delay=1;delay<200;delay++);

   SET_CONFIG_PAGE(CF_PAGE_1);          /* switch on HTRC110 drivers again*/

   for(delay=1;delay<2000;delay++);     /* wait some time for the transponder to reset */

   Fast_Settling ();
}




void main(void)
{
   /*  preparing the wonderful ABIC */

   WRITE_TAG_N(5);        /*set program pulse length */
   
   /*  Configure the HTRC110  to your system:

      Gain = 1000
      Low pass = 6kHz
      High pass = 160Hz
      HTRC110 Clock = 16MHz
   */
   SET_CONFIG_PAGE(CF_PAGE_0+GAIN1+GAIN0+FILTERL+FILTERH);   
   SET_CONFIG_PAGE(CF_PAGE_1);
   SET_CONFIG_PAGE(CF_PAGE_2);
   SET_CONFIG_PAGE(CF_PAGE_3+FSEL1+FSEL0);


   /* Set positive optimum phase */
   Ast_Adjust(0x3F);

   Set_Communication_Mode(TEST_MODE);
   Set_Protocol_Callback(Callback);


   /* Get version string from HTRC120 */
   sleep_copro();
   Crypt_Get_Version(version_block, LONG_VERSION);


   while(1)
   {

      restart_transponder();

      error = 0;

      /* start mutual authentication */
      Set_Memory_Address(cmd);
      Generate_Command(START_AUTHENT,0,1);
      memcpy(cmd_backup, cmd, 2);
      Execute_Command();
      while( Protocol_Active() );
      if( error ) continue;


      /* Write page 5 */
      Set_Memory_Address(cmd);
      Generate_Command(WRITE_PAGE,5,3);         /* 3 command repetitions */
      memcpy(send_block, data_block, 4);        /* set data to transmit  */
      memcpy(send_block_backup, send_block, 4); /* memorize data for verif. */
      memcpy(cmd_backup, cmd, 2);         /* memorize command for verif. */
      Execute_Command();
      while( Protocol_Active() );
      if( error ) continue;

      Set_Memory_Address(cmd);
      Generate_Command(READ_PAGE,5,2);    /* 2 command repetitions       */
      memcpy(cmd_backup, cmd, 2);         /* memorize command for verif. */
      Execute_Command();
      while( Protocol_Active() );
      if( error ) continue;

      Set_Memory_Address(cmd);
      Generate_Command(HALT,0,2);
      memcpy(cmd_backup, cmd, 2);
      Execute_Command();
      while( Protocol_Active() );
      if( error ) continue;
   }
}
