Access System

The Access System is specifically the part of our overall security system that controls doors and devices via rfid.

This thread is a build log so we can keep track of how far along this project is and what needs to be done next.

Current Status

We have most of the parts purchased, we’re waiting on more netrol boards from @lhovo. We need to write down the specific implementation locations, and put bags of parts together for each location.

Next Steps

  • Locating all missing or not yet sourced parts as defined by this spreadsheet, If you know where this stuff is, pipe up in the thread or let us know in person.
  • Assess any components not yet considered, such as what doors should have gas closers. If you have thoughts there please let us know.
  • Modifying the enclosures so that grommets can be installed, this requires someone with time to mill them all
  • Once all parts are in the crate, packaging them out into bags with parts for each implementation location, with documentation in the bag.
  • Installation everywhere!

Semi-Unknowns

  • Do we have poe or power eveywhere needed?
  • Do we have networking cables everywhere needed?

Software Shenannigans

@lhovo and @buzz have both been continuing to hack on the code that runs on our access system. If you’re familiar with C or are reasonably confident with arduino, and you think you can help, pipe up in the thread.

We may need to look into a better server side implementation for this stuff, if you’re a php,javascript,ruby,python person with web experience and spare time, pipe up.

For future reference, the expenditure on this system is being tracked in this spreadsheet:

I’m not licking this cookie but the serverside code on this is on my wishlist.

@theban has installed an RFID reader on the Metal shop and set up a wifi link ready for SNARC installation.

I have installed one on the Woodshop door and have one more waiting to install on the cnc/old metalshop setup pending wireless linking to the HSBNE wifi network (I’m configuring a router for this too.)

I also have two snarcs to configure and install as well.

Thought I had RE this, these snarcs have the ‘emergency stop’ pins unused, would it be worth hooking these up to a reed switch for door status @devians?

1 Like

Another update, there are now RFID swipes installed (pending SNARCs and network infrastructure) on the Art/Creatorium Room, the CNC shop room, the Digital Fabrication Cause room/s,

I’m hoping to come in on the weekend to install more equipment to avoid straya day mate madness.

2 Likes

Thanks to @Thermoelectric’s help today another 3 rfid swipes have been installed, pending SNARC installation.

We also found out that the RFID swipes don’t work when up against the metal wall panels, so we fabricated 5mm spacer plates for all 5 on metal doors and installed them before confirming they worked.

Now onto the networking required for the SNARCs.

Networking done, PoE done.

Card readers are outputting in ABA-TK2 as they’re designed to be direct swap in replacement for Magstripe readers.

Info on how to decode is found at http://blog.tehinterweb.com/?p=60 and we’re trying to refactor the code to support it.

1 Like

I’ve just spent a couple more hours trying to decode the data, with one of these readers, and I’ve failed to get anything more than a string of bytes… so I’m proposing an alternative: since we can definitely read some data from the reader/card combo, and it’s definitely unique to the card, and repeatable, that we just treat that “string of bytes” as a new unique value… so in-essence, each user would get two unique RFID tag/s recorded against their record… teh first being the actual decoded content ( as provided by the current readers), and the other being the ABA-TK2 encoded “byte string” ( as provided by the new readers).
Only Downside is that during enrollment, the card would have to be swiped against two different readers, to get the data for both. Maybe we could make the “enrollment process” something like “go swipe the front door, and then immediately swipe the green room door”?

In all honesty, I’d rather kind of like to go all or nothing and replace all the readers with these so we have a consistant environment. It turns out that ABA TK2 just stands for ‘ABA Track 2’ which is the standard that magstripe readers use to encode data on ‘stripe 2’ of the magstripe.

I’m going to have a crack at decoding it too, it annoys me not to be able to decode it :slight_smile:

After a quick bit of research I’ve found this PHP code which purports to turn the binary strings of data into the right 5-byte strings and handle the parity bits. http://pastebin.com/h9eVqRxz a better description of it is at http://andrewmohawk.com/2012/05/29/magnetic-stripes-part-1/ which explains how to read the track data and crc it

Although this code is written for decoding track 3, track 2 and track 3 are stored the same way (track 1 actually uses 8-byte strings to be even more confusing) and we should be able to adapt it.

The relevant paragraph in that blog post is this, which explains how to decode track 2/3:

So the binary is in the format of a 5 bit character (4 bits for the data and 1 bit for odd-parity checking) and works something like this:

Binary data: 11001
First four for data: 1100
Odd-Parity bit: 1

Looking at the above its first important to know that the parity bit (the last 1) is calculated by making sure there are an odd number of 1′s in the five bit sequence.

Next you can look at the ‘data’ which is 1100. The data is encoded with the least significant bit first, so the in essence it is read backwards and the actual data is 0011. This data can then be taken to decimal (0111 = 3), it is then shifted up 48 characters in the ASCII character set to return the ASCII value, thus the decimal value is 51 which is a 3.

1 Like

For a longer explaination of how to decode, see the below:

Converting bytes to characters

To convert the bytes to characters, first, ignore the last bit of each byte: it’s the “parity” bit, which has already served its purpose.
101000 010010 000010 110010 010010 000010 110010 110010 011001 101001 101001 001101 111111 101100

Then, swap those bytes around: currently, they’re stored least-significant-bit first, and we’re used to reading numbers the other way round (this and the next steps can be done as a single step using a script).
000101 010010 010000 010011 010010 010000 010011 010011 100110 100101 100101 101100 111111 001101

Then, convert them to numbers (wincalc can do this for you, or just do it in your head).
5 18 16 19 18 16 19 19 38 37 37 44 63 13

Add 0x20 (32) to each value for 7-bit tracks, or 0x30 (48) for 5-bit tracks.
37 50 48 51 50 48 51 51 70 69 69 76 95 45

That gives you the ascii value, so convert that to characters.
% 2 0 3 2 0 3 3 F E E L _ -

Converting characters to values

But what does it mean?

Well, that depends on the data format. Once again, there’s a fair bit of standardisation.

Sentinel characters

Sentinel characters are the “framing characters” that let the reader know when the swiping has begun and ended, so they are at the beginning and end of the data. They ideally also let the reader uniquely know which WAY the card was swiped, so it can properly decode the data. Because of this, their values are typically chosen so that the start sentinel cannot be confused with a reversed end sentinel.

5-bit tracks normally begin with a ‘%’ (1010001) as the start sentinel, then have the data, then ‘?’ (1111100) as the end sentinel, possibly followed by one last character.

7-bit tracks normally begin with ‘;’ (11010) as the start sentinel, then have the data, then ‘?’ (11111) as the end sentinel, possibly followed by one last character.

LRC characters

That “one last character” mentioned above is also considered part of the “framing characters”, and like the start and end sentinel, is typically discarded by reading software. It’s called the Longitudinal Redundancy Check (LRC) character, and is used to verify that the data is correct. For each bit in this character (other than the parity bit, which is worked out for this character as normal), it is set to 1 if there are an odd number of other bytes (including sentinels) that have that bit set, and 0 of there’s an even number. This is most easily generated by XORing all the other characters together.

Separator characters

Since each track may store multiple fields of varying length, the fields need to be separated. The usual characters for this are ‘$’ and ‘^’ (7-bit tracks) and ‘=’ (both 5 and 7-bit tracks).

last night, I was trying to use this library: https://github.com/ieatlint/mslib.git … which takes audio data from connecting an actual magstripe reader to your soundcard, and then decodes it. I was able to hack out the audio part, so I could just use it for the bit-to-byte decoding algorithm, and it kinda worked… biut it’s hacky, and may be wrong: ( at this point, it does not seem to decode any data from our readers, but it does decode the demo data that the library porovier gave, which claims to be in the same 5bit, LSB, odd parity stupid sh*ty format.

char bitStream[] = “10100110000010011001000001010011000011010011000011110000000000000000”;

char charStream[ MAX_IATA_LEN + 1 ], curChar;
char LRC[ IATA_CHAR_LEN ] = { 0 };
int bitStreamLen, i, x, len, validSwipe;
int maxLen, charLen, badChars;

maxLen = MAX_ABA_LEN;
charLen = ABA_CHAR_LEN;

validSwipe = 0;

bitStreamLen = strlen( bitStream );

curChar = ‘\0’;
badChars = 0;
 /* Traverse the bitstream to decode all the bits into a charstream /
for( i = 0, len = 0; ( i + charLen ) < bitStreamLen && len < maxLen && curChar != ‘?’; i += charLen, len++ ) {
curChar = _ms_decode_bits_char( bitStream + i, LRC, ABA );
printf(“c:%c”,curChar);
charStream[ len ] = curChar;
if( curChar == BAD_CHAR )
badChars++; /
count the bad chars */
}
charStream[ len ] = ‘\0’;

/* Print warning about any detected bad characters */
if( badChars ) {
fprintf( stderr, “ms_decode_bits(): Warning: %d chars failed parity check\n”, badChars );
validSwipe = 1;
}

printf(“charStream:%s”,charStream);

I think I found the solution,
though I don’t have a reader to try it out.

I believe these are RS232, up until now we have been using ttl.

Links for idea’s on making compatible hardware


I think I have an old “serial dongle” around some place with an actual DB9 on it… it might be classic RS232 ( ie inverted +/- 13volts ) … not sure.

actually, given the reader module/hardware only uses the “transmit” line, and we are using software serial, we should be able to just “fix this in software”, by changing the softwareserial library to “work inverted”, nd maybe using a couple of resistors in a voltage devider to drop the voltage to the appropriate tollerance. ( software serial just bit-bangs the RX line anyway, so no harm done if is 1’s are zeros etc ). someone did something similar here: http://forum.arduino.cc/index.php?topic=11955.0

uh, yeah I’ve been saying from the beginning that these things are RS232. Was that not common knowledge?

Knowledge that was forgotten

Wasn’t forgotten here. The rfid readers are capable of (and will be/are) running at 5v which means the logic voltage won’t be exceeding the TTL spec.

All we have to do is invert the logic, then interpret it from there :slight_smile:

I’m testing that theory right now.

Just in case, I’ve bought a bunch (20) of MAX3232 breakout boards to turn the rs232 on these to standard ttl.

For reference, this is the exact module - http://www.banggood.com/5Pcs-Serial-Port-Mini-RS232-To-TTL-Converter-Adapter-MAX3232CSE-p-965989.html

I haven’t had much luck translating the bytes by hand, as @buzz pointed out the other night the parity bits were wrong every time.

sigh, I triple checked with people before we bought these things. we had a choice of weigand and rs232 and everyone said ‘yep, 232 is easy as heck and we don’t have the pins on old snarcs to do weigand but we do to do rs232’

so whats changed?