248 lines
6.0 KiB
C
Executable File
248 lines
6.0 KiB
C
Executable File
/*
|
|
ifd_phoenix.c
|
|
This module provides IFD handling functions for Smartmouse/Phoenix reader.
|
|
*/
|
|
|
|
#include "../globals.h"
|
|
|
|
#ifdef CARDREADER_PHOENIX
|
|
#include "../oscam-time.h"
|
|
#include "icc_async.h"
|
|
#include "ifd_db2com.h"
|
|
#include "ifd_phoenix.h"
|
|
#include "io_serial.h"
|
|
|
|
#define OK 0
|
|
#define ERROR 1
|
|
|
|
#define GPIO_PIN (1 << (reader->detect - 4))
|
|
|
|
static inline int reader_use_gpio(struct s_reader *reader)
|
|
{
|
|
return reader->use_gpio && reader->detect > 4;
|
|
}
|
|
|
|
static void set_gpio(struct s_reader *reader, int32_t level)
|
|
{
|
|
int ret = 0;
|
|
|
|
ret |= read(reader->gpio_outen, &reader->gpio, sizeof(reader->gpio));
|
|
reader->gpio |= GPIO_PIN;
|
|
ret |= write(reader->gpio_outen, &reader->gpio, sizeof(reader->gpio));
|
|
|
|
ret |= read(reader->gpio_out, &reader->gpio, sizeof(reader->gpio));
|
|
if(level > 0)
|
|
{ reader->gpio |= GPIO_PIN; }
|
|
else
|
|
{ reader->gpio &= ~GPIO_PIN; }
|
|
ret |= write(reader->gpio_out, &reader->gpio, sizeof(reader->gpio));
|
|
|
|
rdr_log_dbg(reader, D_IFD, "%s level: %d ret: %d", __func__, level, ret);
|
|
}
|
|
|
|
static void set_gpio_input(struct s_reader *reader)
|
|
{
|
|
int ret = 0;
|
|
ret |= read(reader->gpio_outen, &reader->gpio, sizeof(reader->gpio));
|
|
reader->gpio &= ~GPIO_PIN;
|
|
ret |= write(reader->gpio_outen, &reader->gpio, sizeof(reader->gpio));
|
|
rdr_log_dbg(reader, D_IFD, "%s ret:%d", __func__, ret);
|
|
}
|
|
|
|
static int32_t get_gpio(struct s_reader *reader)
|
|
{
|
|
int ret = 0;
|
|
set_gpio_input(reader);
|
|
ret = read(reader->gpio_in, &reader->gpio, sizeof(reader->gpio));
|
|
rdr_log_dbg(reader, D_IFD, "%s ok:%d ret:%d", __func__, reader->gpio & GPIO_PIN, ret);
|
|
if(reader->gpio & GPIO_PIN)
|
|
{ return OK; }
|
|
else
|
|
{ return ERROR; }
|
|
}
|
|
|
|
int32_t Phoenix_Init(struct s_reader *reader)
|
|
{
|
|
// First set card in reset state, to not change any parameters while communication ongoing
|
|
IO_Serial_RTS_Set(reader);
|
|
|
|
const struct s_cardreader *crdr_ops = reader->crdr;
|
|
if (!crdr_ops) return ERROR;
|
|
|
|
if(crdr_ops->flush) { IO_Serial_Flush(reader); }
|
|
|
|
// define reader->gpio number used for card detect and reset. ref to globals.h
|
|
if(reader_use_gpio(reader))
|
|
{
|
|
reader->gpio_outen = open("/dev/gpio/outen", O_RDWR);
|
|
reader->gpio_out = open("/dev/gpio/out", O_RDWR);
|
|
reader->gpio_in = open("/dev/gpio/in", O_RDWR);
|
|
rdr_log_dbg(reader, D_IFD, "init gpio_outen:%d gpio_out:%d gpio_in:%d",
|
|
reader->gpio_outen, reader->gpio_out, reader->gpio_in);
|
|
set_gpio_input(reader);
|
|
}
|
|
|
|
rdr_log_dbg(reader, D_IFD, "Initializing reader type=%d", reader->typ);
|
|
|
|
/* Default serial port settings */
|
|
if(reader->atr[0] == 0)
|
|
{
|
|
if(IO_Serial_SetParams(reader, DEFAULT_BAUDRATE, 8, PARITY_EVEN, 2, NULL, NULL)) { return ERROR; }
|
|
if(crdr_ops->flush) { IO_Serial_Flush(reader); }
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
int32_t Phoenix_GetStatus(struct s_reader *reader, int32_t *status)
|
|
{
|
|
// detect card via defined reader->gpio
|
|
if(reader_use_gpio(reader))
|
|
{
|
|
*status = !get_gpio(reader);
|
|
return OK;
|
|
}
|
|
else
|
|
{
|
|
return IO_Serial_GetStatus(reader, status);
|
|
}
|
|
}
|
|
|
|
int32_t Phoenix_Reset(struct s_reader *reader, ATR *atr)
|
|
{
|
|
rdr_log_dbg(reader, D_IFD, "Resetting card");
|
|
int32_t ret;
|
|
int32_t i;
|
|
unsigned char buf[ATR_MAX_SIZE];
|
|
int32_t parity[3] = {PARITY_EVEN, PARITY_ODD, PARITY_NONE};
|
|
|
|
call(IO_Serial_SetBaudrate(reader, DEFAULT_BAUDRATE));
|
|
|
|
const struct s_cardreader *crdr_ops = reader->crdr;
|
|
if (!crdr_ops) return ERROR;
|
|
|
|
for(i = 0; i < 3; i++)
|
|
{
|
|
if(crdr_ops->flush) { IO_Serial_Flush(reader); }
|
|
if(crdr_ops->set_parity) { IO_Serial_SetParity(reader, parity[i]); }
|
|
|
|
ret = ERROR;
|
|
|
|
IO_Serial_Ioctl_Lock(reader, 1);
|
|
if(reader_use_gpio(reader))
|
|
{ set_gpio(reader, 0); }
|
|
else
|
|
{ IO_Serial_RTS_Set(reader); }
|
|
|
|
cs_sleepms(50);
|
|
|
|
// felix: set card reset hi (inactive)
|
|
if(reader_use_gpio(reader))
|
|
{ set_gpio_input(reader); }
|
|
else
|
|
{ IO_Serial_RTS_Clr(reader); }
|
|
cs_sleepms(50);
|
|
IO_Serial_Ioctl_Lock(reader, 0);
|
|
|
|
int32_t n = 0;
|
|
while(n < ATR_MAX_SIZE && !IO_Serial_Read(reader, 0, ATR_TIMEOUT, 1, buf + n))
|
|
{ n++; }
|
|
if(n == 0)
|
|
{ continue; }
|
|
if(ATR_InitFromArray(atr, buf, n) != ERROR)
|
|
{ ret = OK; }
|
|
// Successfully retrieve ATR
|
|
if(ret == OK)
|
|
{ break; }
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
int32_t Phoenix_Close(struct s_reader *reader)
|
|
{
|
|
rdr_log_dbg(reader, D_IFD, "Closing phoenix device %s", reader->device);
|
|
if(reader_use_gpio(reader))
|
|
{
|
|
if(reader->gpio_outen > -1)
|
|
{ close(reader->gpio_outen); }
|
|
if(reader->gpio_out > -1)
|
|
{ close(reader->gpio_out); }
|
|
if(reader->gpio_in > -1)
|
|
{ close(reader->gpio_in); }
|
|
}
|
|
IO_Serial_Close(reader);
|
|
return OK;
|
|
}
|
|
|
|
/*
|
|
int32_t Phoenix_FastReset (struct s_reader * reader, int32_t delay)
|
|
{
|
|
IO_Serial_Ioctl_Lock(reader, 1);
|
|
if (reader_use_gpio(reader))
|
|
set_gpio(reader, 0);
|
|
else
|
|
IO_Serial_RTS_Set(reader);
|
|
|
|
cs_sleepms(delay);
|
|
|
|
// set card reset hi (inactive)
|
|
if (reader_use_gpio(reader))
|
|
set_gpio_input(reader);
|
|
else
|
|
IO_Serial_RTS_Clr(reader);
|
|
|
|
IO_Serial_Ioctl_Lock(reader, 0);
|
|
|
|
cs_sleepms(50);
|
|
|
|
IO_Serial_Flush(reader);
|
|
return 0;
|
|
|
|
}
|
|
*/
|
|
static int32_t mouse_init(struct s_reader *reader)
|
|
{
|
|
const struct s_cardreader *crdr_ops = reader->crdr;
|
|
if (!crdr_ops) return ERROR;
|
|
|
|
if(detect_db2com_reader(reader))
|
|
{
|
|
reader->crdr = crdr_ops = &cardreader_db2com;
|
|
return crdr_ops->reader_init(reader);
|
|
}
|
|
|
|
reader->handle = open(reader->device, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
|
if(reader->handle < 0)
|
|
{
|
|
rdr_log(reader, "ERROR: Opening device %s (errno=%d %s)",
|
|
reader->device, errno, strerror(errno));
|
|
return ERROR;
|
|
}
|
|
if(Phoenix_Init(reader))
|
|
{
|
|
rdr_log(reader, "ERROR: Phoenix_Init returns error");
|
|
Phoenix_Close(reader);
|
|
return ERROR;
|
|
}
|
|
return OK;
|
|
}
|
|
|
|
const struct s_cardreader cardreader_mouse =
|
|
{
|
|
.desc = "mouse",
|
|
.typ = R_MOUSE,
|
|
.flush = 1,
|
|
.read_written = 1,
|
|
.need_inverse = 1,
|
|
.reader_init = mouse_init,
|
|
.get_status = Phoenix_GetStatus,
|
|
.activate = Phoenix_Reset,
|
|
.transmit = IO_Serial_Transmit,
|
|
.receive = IO_Serial_Receive,
|
|
.close = Phoenix_Close,
|
|
.set_parity = IO_Serial_SetParity,
|
|
.set_baudrate = IO_Serial_SetBaudrate,
|
|
};
|
|
|
|
#endif
|