/*
t1_block.h
T=1 block abstract data type implementation
This file is part of the Unix driver for Towitoko smartcard readers
Copyright (C) 2000 Carlos Prados <cprados@yahoo.com>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "t1_block.h"
#include <stdlib.h>
#include <string.h>
/*
* Not exported constants definition
*/
#define T1_BLOCK_NAD 0x00
/*
* Not exported functions declaration
*/
static BYTE
T1_Block_LRC (BYTE * data, unsigned length);
/*
* Exported functions definition
*/
T1_Block *
T1_Block_New (BYTE * buffer, unsigned length)
{
T1_Block * block;
if (length < 4)
return NULL;
block = (T1_Block *) malloc (sizeof (T1_Block));
if (block != NULL)
{
block->length = MIN(length, T1_BLOCK_MAX_SIZE);
block->data = (BYTE *) calloc (block->length, sizeof (BYTE));
if (block->data != NULL)
{
memcpy (block->data, buffer, block->length);
}
else
{
free (block);
block = NULL;
}
}
return block;
}
T1_Block *
T1_Block_NewIBlock (BYTE len, BYTE * inf, BYTE ns, bool more)
{
T1_Block * block;
block = (T1_Block *) malloc (sizeof (T1_Block));
if (block != NULL)
{
block->length = len + 4;
block->data = (BYTE *) calloc (block->length, sizeof (BYTE));
if (block->data != NULL)
{
block->data[0] = T1_BLOCK_NAD;
block->data[1] = T1_BLOCK_I | ((ns << 6) & 0x40);
if (more)
block->data[1] |= 0x20;
block->data[2] = len;
if (len != 0x00)
memcpy (block->data + 3, inf, len);
block->data[len+3] = T1_Block_LRC (block->data, len+3);
}
else
{
free (block);
block = NULL;
}
}
return block;
}
T1_Block *
T1_Block_NewRBlock (BYTE type, BYTE nr)
{
T1_Block * block;
block = (T1_Block *) malloc (sizeof (T1_Block));
if (block != NULL)
{
block->length = 4;
block->data = (BYTE *) calloc (block->length, sizeof (BYTE));
if (block->data != NULL)
{
block->data[0] = T1_BLOCK_NAD;
block->data[1] = type | ((nr << 4) & 0x10);
block->data[2] = 0x00;
block->data[3] = T1_Block_LRC (block->data, 3);
}
else
{
free (block);
block = NULL;
}
}
return block;
}
T1_Block *
T1_Block_NewSBlock (BYTE type, BYTE len, BYTE * inf)
{
T1_Block * block;
block = (T1_Block *) malloc (sizeof (T1_Block));
if (block != NULL)
{
block->length = 4 + len;
block->data = (BYTE *) calloc (block->length, sizeof (BYTE));
if (block->data != NULL)
{
block->data[0] = T1_BLOCK_NAD;
block->data[1] = type;
block->data[2] = len;
if (len != 0x00)
memcpy (block->data + 3, inf, len);
block->data[len+3] = T1_Block_LRC (block->data, len+3);
}
else
{
free (block);
block = NULL;
}
}
return block;
}
BYTE
T1_Block_GetType (T1_Block * block)
{
if ((block->data[1] & 0x80) == T1_BLOCK_I)
return T1_BLOCK_I;
return (block->data[1] & 0xEF);
}
BYTE
T1_Block_GetNS (T1_Block * block)
{
return ((block->data[1] >> 6)& 0x01);
}
bool
T1_Block_GetMore (T1_Block * block)
{
return ((block->data[1] >> 5) & 0x01);
}
BYTE
T1_Block_GetNR (T1_Block * block)
{
return ((block->data[1] >> 4) & 0x01);
}
BYTE
T1_Block_GetLen (T1_Block * block)
{
return block->data[2];
}
BYTE *
T1_Block_GetInf (T1_Block * block)
{
if (block->length < 5)
return NULL;
return block->data + 3;
}
BYTE *
T1_Block_Raw (T1_Block * block)
{
return block->data;
}
unsigned
T1_Block_RawLen (T1_Block * block)
{
return block->length;
}
void
T1_Block_Delete (T1_Block * block)
{
free (block->data);
free (block);
}
/*
* Not exported functions definition
*/
static BYTE
T1_Block_LRC (BYTE * data, unsigned length)
{
BYTE lrc;
unsigned i;
lrc = 0x00;
for (i = 0; i < length; i++)
{
lrc ^= data[i];
}
return lrc;
}
syntax highlighted by Code2HTML, v. 0.9.1