Skip to content

Commit

Permalink
add bc_combine for combining swipes from same card
Browse files Browse the repository at this point in the history
bc_combine combines the data from forward and backward swipes of a
particular card.  Currently only track 2 is combined for testing
purposes.

A driver for bc_combine was added (combine.c).  It accepts a set of
forward swipes in the first 3 lines of standard in, followed by a set of
backward swipes in the second 3 lines of standard in.

BCERR_UNIMPLEMENTED was added to the error codes for referring to
unimplemented behavior in bc_combine.

Testing the bc_combine driver on 16 different cards showed that the
swipes from 13 cards could be successfully combined, while the swipes of
3 cards could not.  This should improve with future changes to
bc_combine.
  • Loading branch information
ossguy committed Feb 16, 2009
1 parent cd98639 commit 481d52a
Show file tree
Hide file tree
Showing 4 changed files with 172 additions and 1 deletion.
8 changes: 7 additions & 1 deletion Makefile
Expand Up @@ -18,14 +18,20 @@
CC = gcc
CFLAGS = -ansi -pedantic -Wall -Werror

all: driver
all: driver combine

driver: driver.o libbitconvert.a
$(CC) $(CFLAGS) -o driver driver.o -L. -lbitconvert -lpcre

driver.o: driver.c bitconvert.h
$(CC) $(CFLAGS) -c driver.c

combine: combine.o libbitconvert.a
$(CC) $(CFLAGS) -o combine combine.o -L. -lbitconvert -lpcre

combine.o: combine.c bitconvert.h
$(CC) $(CFLAGS) -c combine.c

bitconvert.o: bitconvert.c bitconvert.h
$(CC) $(CFLAGS) -c bitconvert.c

Expand Down
70 changes: 70 additions & 0 deletions bitconvert.c
Expand Up @@ -424,6 +424,69 @@ int bc_decode_fields(struct bc_decoded* d)
return rv;
}

int bc_combine_track(char* forward, char* backward, char* combined)
{
size_t forward_len;
size_t backward_len;
char* forward_pos;
char* backward_pos;
char* forward_start;
size_t end_zeroes;

/* ensure the input consists of exclusively 0s and 1s and find length */

forward_len = strspn(forward, "01");
backward_len = strspn(backward, "01");

if (forward[forward_len] != '\0') {
/* TODO: set the error string to specify forward track */
/* TODO: find way to also print track number; another param? */
return BCERR_INVALID_INPUT;
}
if (backward[backward_len] != '\0') {
/* TODO: set the error string to specify backward track */
return BCERR_INVALID_INPUT;
}


/* TODO: we won't need this once we change to dynamic allocation */
if (forward_len + backward_len + 1 > BC_T2_INPUT_SIZE) {
/* TODO: should be BCERR_INPUT_FULL but I'm not making new error
* code for something that will be removed soon anyway
*/
return BCERR_RESULT_FULL;
}

forward_pos = strchr(forward, (int)'1');
backward_pos = strrchr(backward, (int)'1');

/* don't bother handling empty strings; too much work for now */
/* TODO: should handle this or make it unnecessary */
if (NULL == forward_pos || NULL == backward_pos) {
return BCERR_UNIMPLEMENTED;
}

end_zeroes = &(backward[backward_len]) - backward_pos;
forward_start = forward_pos;

while (forward_pos != &(forward[forward_len]) &&
backward_pos != backward) {

if (backward_pos[0] != forward_pos[0]) {
return -1;
}

forward_pos++;
backward_pos--;
}

memset(combined, '0', end_zeroes);
memcpy(&(combined[end_zeroes]), forward_start,
&(forward[forward_len]) - forward_start);

return 0;
}

void bc_init(struct bc_input* in, void (*error_callback)(const char*))
{
in->t1[0] = '\0';
Expand Down Expand Up @@ -501,6 +564,12 @@ int bc_find_fields(struct bc_decoded* result)
return bc_decode_fields(result);
}

int bc_combine(struct bc_input* forward, struct bc_input* backward,
struct bc_input* combined)
{
return bc_combine_track(forward->t2, backward->t2, combined->t2);
}

const char* bc_strerror(int err)
{
switch (err)
Expand All @@ -517,6 +586,7 @@ const char* bc_strerror(int err)
case BCERR_NO_MATCHING_FORMAT: return "No matching format";
case BCERR_BAD_FORMAT_ENCODING_TYPE: return "Bad format encoding type";
case BCERR_FORMAT_MISSING_RE: return "Format missing regular expression";
case BCERR_UNIMPLEMENTED: return "Unimplemented";
default: return "Unknown error";
}
}
3 changes: 3 additions & 0 deletions bitconvert.h
Expand Up @@ -42,6 +42,7 @@ extern "C" {
#define BCERR_NO_MATCHING_FORMAT 9
#define BCERR_BAD_FORMAT_ENCODING_TYPE 10
#define BCERR_FORMAT_MISSING_RE 11
#define BCERR_UNIMPLEMENTED 12

#define BC_ENCODING_NONE -1 /* track has no data; not the same as binary */
#define BC_ENCODING_BINARY 1
Expand Down Expand Up @@ -101,6 +102,8 @@ void bc_init(struct bc_input* in, void (*error_callback)(const char*));

int bc_decode(struct bc_input* in, struct bc_decoded* result);
int bc_find_fields(struct bc_decoded* result);
int bc_combine(struct bc_input* forward, struct bc_input* backward,
struct bc_input* combined);
const char* bc_strerror(int err);

#ifdef __cplusplus
Expand Down
92 changes: 92 additions & 0 deletions combine.c
@@ -0,0 +1,92 @@
/*
* combine.c - test driver for bc_combine in libbitconvert
* This file is part of libbitconvert.
*
* Copyright (c) 2008-2009, Denver Gingerich <denver@ossguy.com>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include "bitconvert.h"
#include <stdio.h> /* FILE, fgets, printf */
#include <string.h> /* strlen */


char* get_track(FILE* input, char* bits, int bits_len)
{
int bits_end;

if (NULL == fgets(bits, bits_len, input))
{
return NULL;
}
bits_end = strlen(bits);

/* strip trailing newline */
if ('\n' == bits[bits_end - 1])
{
bits[bits_end - 1] = '\0';
}

return bits;
}

void print_error(const char* error)
{
printf("%s\n", error);
}

int main(void)
{
FILE* input;
struct bc_input forward;
struct bc_input backward;
struct bc_input combined;
int rv;

input = stdin;
bc_init(&forward, print_error);
bc_init(&backward, print_error);
bc_init(&combined, print_error);

while (1)
{
if (NULL == get_track(input, forward.t1, sizeof(forward.t1)))
break;
if (NULL == get_track(input, forward.t2, sizeof(forward.t2)))
break;
if (NULL == get_track(input, forward.t3, sizeof(forward.t3)))
break;

if (NULL == get_track(input, backward.t1, sizeof(backward.t1)))
break;
if (NULL == get_track(input, backward.t2, sizeof(backward.t2)))
break;
if (NULL == get_track(input, backward.t3, sizeof(backward.t3)))
break;

rv = bc_combine(&forward, &backward, &combined);

printf("Result: %d (%s)\n", rv, bc_strerror(rv));
printf("Track 1 - data_len: %lu, data:\n`%s`\n",
(unsigned long)strlen(combined.t1), combined.t1);
printf("Track 2 - data_len: %lu, data:\n`%s`\n",
(unsigned long)strlen(combined.t2), combined.t2);
printf("Track 3 - data_len: %lu, data:\n`%s`\n",
(unsigned long)strlen(combined.t3), combined.t3);
}

fclose(input);

return 0;
}

0 comments on commit 481d52a

Please sign in to comment.