oscam-2.26.01-11942-802-wit.../csctapi/ifd_azbox.c
2026-02-17 10:06:53 +00:00

173 lines
5.0 KiB
C
Executable File

#include"../globals.h"
#ifdef CARDREADER_INTERNAL_AZBOX
#include "../oscam-time.h"
#include "atr.h"
#include "../extapi/openxcas/openxcas_api.h"
#include "../extapi/openxcas/openxcas_smartcard.h"
#include "io_serial.h"
#define OK 0
#define ERROR 1
static int32_t sc_mode;
static int32_t _GetStatus(struct s_reader *reader)
{
unsigned char buf[64];
memset(buf, 0, sizeof(buf));
return ioctl(reader->handle, SCARD_IOC_CHECKCARD, &buf);
}
static int32_t Azbox_Reader_Init(struct s_reader *reader)
{
rdr_log_dbg(reader, D_DEVICE, "Init");
if((reader->handle = openxcas_get_smartcard_device(0)) < 0)
{
rdr_log_dbg(reader, D_DEVICE, "Init reader failed");
return 0;
}
rdr_log_dbg(reader, D_DEVICE, "Init reader %d succeeded", reader->handle);
return OK;
}
static int32_t Azbox_SetMode(struct s_reader *reader, int32_t mode)
{
sc_mode = mode;
rdr_log(reader, "sc_mode %d", sc_mode);
return OK;
}
static int32_t Azbox_GetStatus(struct s_reader *reader, int32_t *status)
{
int32_t card_status = _GetStatus(reader);
if(card_status != 0x03 && card_status != 0x01)
{ *status = 0; }
else
{ *status = 1; }
//rdr_log_dbg(reader, D_IFD, "openxcas sc: status = %d", *status);
return OK;
}
static int32_t Azbox_Reset(struct s_reader *reader, ATR *atr)
{
rdr_log_dbg(reader, D_IFD, "Azbox resetting card");
unsigned char buf[ATR_MAX_SIZE];
int32_t card_status;
buf[0] = 0x03;
buf[1] = 0x01;
card_status = ioctl(reader->handle, SCARD_IOC_WARMRESET, &buf);
while((card_status = _GetStatus(reader)) != 0x03)
{ cs_sleepms(50); }
buf[0] = 0x02;
buf[1] = sc_mode;
sc_mode = ioctl(reader->handle, SCARD_IOC_CHECKCARD, &buf);
int32_t frequency;
frequency = reader->cardmhz * 10000L;
rdr_log(reader, "Set reader mhz = %.2f", (float) frequency / 1000000L);
int32_t n = 0;
buf[0] = 0x01;
n = ioctl(reader->handle, SCARD_IOC_CHECKCARD, &buf);
//cs_sleepms(50);
rdr_log_dbg(reader, D_IFD, "Waiting for card ATR Response...");
int32_t FI = (buf[n] >> 4);
int32_t Fi = atr_f_table[FI];
float fmax = atr_fs_table[FI];
int32_t D = ATR_DEFAULT_D;
int32_t DI = (buf[n] & 0x0F);
D = atr_d_table[DI];
rdr_log_dbg(reader, D_ATR, "Advertised max cardfrequency is %.2f (Fmax), frequency divider is %d", fmax / 1000000L, Fi);
if(D == 0) { D = 1;}
rdr_log_dbg(reader, D_ATR, "Bitrate adjustment is %d (D)", D);
rdr_log_dbg(reader, D_ATR, "Work ETU = %.2f us assuming card runs at %.2f Mhz", (double)((double)(1 / (double)D) * ((double)Fi / (double)((double)frequency / 1000000))), (float) frequency / 1000000);
rdr_log_dbg(reader, D_ATR, "Initial ETU = %.2f us", (double)372 / (double)frequency * 1000000);
rdr_log_dbg(reader, D_IFD, "ATR Fsmax is %.2f MHz, Work ETU is %.2f us, clocking card to %.2f MHz",
fmax / 1000000, (double)((double)(1 / (double)D) * ((double)Fi / (double)((double)frequency / 1000000))), (float) frequency / 1000000);
if(ATR_InitFromArray(atr, buf, n) == ERROR)
{
rdr_log(reader, "WARNING: ATR is invalid!");
return ERROR;
}
rdr_log_dbg(reader, D_IFD, "Card activated");
return OK;
}
static int32_t Azbox_Reader_Close(struct s_reader *reader)
{
rdr_log_dbg(reader, D_IFD, "Deactivating card");
if((reader->handle = openxcas_release_smartcard_device(0)) > 0)
{
rdr_log_dbg(reader, D_DEVICE, "Closing reader %d", reader->handle);
return 0;
}
return OK;
}
static int32_t Azbox_do_reset(struct s_reader *reader, struct s_ATR *atr,
int32_t (*rdr_activate_card)(struct s_reader *, struct s_ATR *, uint16_t deprecated),
int32_t (*rdr_get_cardsystem)(struct s_reader *, struct s_ATR *))
{
int32_t ret = 0;
int32_t i;
if(reader->azbox_mode != -1)
{
Azbox_SetMode(reader, reader->azbox_mode);
if(!rdr_activate_card(reader, atr, 0))
{ return -1; }
ret = rdr_get_cardsystem(reader, atr);
}
else
{
for(i = 0; i < AZBOX_MODES; i++)
{
Azbox_SetMode(reader, i);
if(!rdr_activate_card(reader, atr, 0))
{ return -1; }
ret = rdr_get_cardsystem(reader, atr);
if(ret)
{ break; }
}
}
return ret;
}
const struct s_cardreader cardreader_internal_azbox =
{
.desc = "internal",
.typ = R_INTERNAL,
.reader_init = Azbox_Reader_Init,
.get_status = Azbox_GetStatus,
.activate = Azbox_Reset,
.transmit = IO_Serial_Transmit,
.receive = IO_Serial_Receive,
.close = Azbox_Reader_Close,
.do_reset = Azbox_do_reset,
};
#endif