librfid/utils/send_script.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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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);
}