293 lines
5.9 KiB
C
293 lines
5.9 KiB
C
/*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2
|
|
* as published by the Free Software Foundation
|
|
*
|
|
* This program 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 General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <errno.h>
|
|
#include <ctype.h>
|
|
|
|
#define _GNU_SOURCE
|
|
#include <getopt.h>
|
|
|
|
#include <librfid/rfid.h>
|
|
#include <librfid/rfid_reader.h>
|
|
#include <librfid/rfid_layer2.h>
|
|
#include <librfid/rfid_protocol.h>
|
|
|
|
#include <librfid/rfid_protocol_mifare_classic.h>
|
|
#include <librfid/rfid_protocol_mifare_ul.h>
|
|
|
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
|
|
|
static const char *
|
|
hexdump(const void *data, unsigned int len)
|
|
{
|
|
static char string[2048];
|
|
unsigned char *d = (unsigned char *) data;
|
|
unsigned int i, left, llen = len;
|
|
|
|
string[0] = '\0';
|
|
left = sizeof(string);
|
|
for (i = 0; llen--; i += 3) {
|
|
if (i >= sizeof(string) -4)
|
|
break;
|
|
snprintf(string+i, 4, " %02x", *d++);
|
|
} return string;
|
|
|
|
if (i >= sizeof(string) -2)
|
|
return string;
|
|
snprintf(string+i, 2, " ");
|
|
i++; llen = len;
|
|
|
|
d = (unsigned char *) data;
|
|
for (; llen--; i += 1) {
|
|
if (i >= sizeof(string) -2)
|
|
break;
|
|
snprintf(string+i, 2, "%c", isprint(*d) ? *d : '.');
|
|
d++;
|
|
}
|
|
return string;
|
|
}
|
|
|
|
static struct rfid_reader_handle *rh;
|
|
static struct rfid_layer2_handle *l2h;
|
|
static struct rfid_protocol_handle *ph;
|
|
|
|
static int init()
|
|
{
|
|
unsigned char buf[0x3f];
|
|
int rc;
|
|
|
|
printf("initializing librfid\n");
|
|
rfid_init();
|
|
|
|
printf("opening reader handle\n");
|
|
rh = rfid_reader_open(NULL, RFID_READER_CM5121);
|
|
if (!rh) {
|
|
fprintf(stderr, "error, no cm5121 handle\n");
|
|
return -1;
|
|
}
|
|
|
|
printf("opening layer2 handle\n");
|
|
l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443A);
|
|
//l2h = rfid_layer2_init(rh, RFID_LAYER2_ISO14443B);
|
|
if (!l2h) {
|
|
fprintf(stderr, "error during iso14443a_init\n");
|
|
return -1;
|
|
}
|
|
|
|
//rc632_register_dump(rh->ah, buf);
|
|
|
|
printf("running layer2 anticol\n");
|
|
rc = rfid_layer2_open(l2h);
|
|
if (rc < 0) {
|
|
fprintf(stderr, "error during layer2_open\n");
|
|
return rc;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int l3(int protocol)
|
|
{
|
|
printf("running layer3 (ats)\n");
|
|
ph = rfid_protocol_init(l2h, protocol);
|
|
if (!ph) {
|
|
fprintf(stderr, "error during protocol_init\n");
|
|
return -1;
|
|
}
|
|
if (rfid_protocol_open(ph) < 0) {
|
|
fprintf(stderr, "error during protocol_open\n");
|
|
return -1;
|
|
}
|
|
|
|
printf("we now have layer3 up and running\n");
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int send_command(char* sbuf, int slen, char* rbuf, int rlen)
|
|
{
|
|
int rv;
|
|
static int doit;
|
|
int answer, c = 0;
|
|
|
|
if(doit == 0) {
|
|
fprintf(stderr, "?? %s (%i bytes)\n", hexdump(sbuf, slen), slen);
|
|
fprintf(stderr, "Execute? (Yes/No/All/Exit) ");
|
|
answer = getc(stdin);
|
|
if(answer != '\n') do {
|
|
c = getc(stdin);
|
|
} while(c != '\n' && c != EOF);
|
|
switch(answer) {
|
|
case 'y': // Fall-through
|
|
case 'Y':
|
|
case '\n':
|
|
// Do nothing
|
|
break;
|
|
case 'n': // Fall-through
|
|
case 'N':
|
|
return 0;
|
|
break;
|
|
case 'a': // Fall-through
|
|
case 'A':
|
|
doit = 1;
|
|
break;
|
|
case 'e': // Fall-through
|
|
case 'E':
|
|
return -1;
|
|
break;
|
|
default:
|
|
return 0; // Default to 'n'
|
|
break;
|
|
}
|
|
}
|
|
|
|
printf(">> %s (%i bytes)\n", hexdump(sbuf, slen), slen);
|
|
|
|
rv = rfid_protocol_transceive(ph, sbuf, slen, rbuf, &rlen, 0, 0);
|
|
if (rv < 0) {
|
|
fprintf(stderr, "Error from transceive: %i\n", rv);
|
|
return rv;
|
|
}
|
|
|
|
printf("<< %s (%i bytes)\n", hexdump(rbuf, rlen), rlen);
|
|
|
|
if(rlen < 2 || rbuf[rlen-2] != (char)0x90 || rbuf[rlen-1] != 0x00) {
|
|
fprintf(stderr, "SW is not 90 00. Ignore (i) or Abort (a)? ");
|
|
answer = getc(stdin);
|
|
if(answer != '\n') do {
|
|
c = getc(stdin);
|
|
} while(c != '\n' && c != EOF);
|
|
switch(answer) {
|
|
case 'i': // Fall-through
|
|
case 'I':
|
|
case '\n':
|
|
// Do nothing
|
|
break;
|
|
case 'a': // Fall-through
|
|
case 'A':
|
|
return -1;
|
|
break;
|
|
default:
|
|
return -1; // Default to 'a'
|
|
}
|
|
}
|
|
|
|
return rlen;
|
|
}
|
|
|
|
static char *nextline(FILE* fh)
|
|
{
|
|
int buflen = 1024; // FIXME Might want to increase dynamically?
|
|
char *buffer = malloc(buflen);
|
|
if (!buffer) {
|
|
perror("malloc");
|
|
return 0;
|
|
}
|
|
|
|
if (!fgets(buffer, buflen, fh)) {
|
|
perror("fgets");
|
|
free(buffer);
|
|
return 0;
|
|
}
|
|
|
|
return buffer;
|
|
}
|
|
|
|
static int unhexchar(char c) {
|
|
if ((c - '0') >= 0 && (c - '0') < 10)
|
|
return c-'0';
|
|
if ((c - 'a') >= 0 && (c - 'a') < 6)
|
|
return 10 + c-'a';
|
|
if ((c - 'A') >= 0 && (c - 'A') < 6)
|
|
return 10 + c-'A';
|
|
return -1;
|
|
}
|
|
|
|
int make_command( const char *line, char **buffer, int *blen )
|
|
{
|
|
int len = strlen(line), pos;
|
|
*buffer = malloc( len );
|
|
*blen = 0;
|
|
if(!*buffer) {
|
|
perror("malloc");
|
|
return 0;
|
|
}
|
|
|
|
for(pos = 0; pos < len; pos++) {
|
|
if(!isxdigit(line[pos]))
|
|
continue;
|
|
if(! (pos+1 < len) )
|
|
continue;
|
|
|
|
(*buffer)[*blen] = unhexchar(line[pos]) * 16 + unhexchar(line[pos+1]);
|
|
pos += 1;
|
|
*blen += 1;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
FILE *fh;
|
|
int slen, rlen, retval = 0;
|
|
char *next, *sbuf, *rbuf;
|
|
|
|
if (argc != 2) {
|
|
fprintf(stderr, "Syntax: %s scriptfile\n", argv[0]);
|
|
exit(1);
|
|
}
|
|
|
|
fh = fopen(argv[1], "r");
|
|
if (!fh) {
|
|
perror("fopen");
|
|
exit(1);
|
|
}
|
|
|
|
if (init() < 0)
|
|
exit(1);
|
|
|
|
if (l3(RFID_PROTOCOL_TCL) < 0)
|
|
exit(1);
|
|
|
|
printf("Protocol T=CL\n");
|
|
/* we've established T=CL at this point */
|
|
|
|
while (next = nextline(fh)) {
|
|
if (!(strlen(next) >= 2 && strncmp(next, "//", 2) == 0)) {
|
|
if (make_command(next, &sbuf, &slen)) {
|
|
rlen = 1024;
|
|
rbuf = calloc(rlen, 1);
|
|
|
|
retval = send_command(sbuf, slen, rbuf, rlen);
|
|
|
|
free(sbuf);
|
|
free(rbuf);
|
|
}
|
|
}
|
|
free(next);
|
|
|
|
if (retval < 0)
|
|
break;
|
|
}
|
|
|
|
rfid_reader_close(rh);
|
|
|
|
exit(0);
|
|
}
|