--- /dev/null
+## see README file
+
+TARGET = tuer
+INSTALL_DIR = /flash/realraum/firmware/arduino
+PORT = /dev/ttyUSB0
+UPLOAD_RATE = 19200
+AVRDUDE_PROGRAMMER = stk500v1
+MCU = atmega168
+F_CPU = 16000000
+
+############################################################################
+# Below here nothing should be changed...
+
+ARDUINO = $(INSTALL_DIR)/hardware/cores/arduino
+AVR_TOOLS_PATH = /usr/bin
+SRC = $(ARDUINO)/pins_arduino.c $(ARDUINO)/wiring.c \
+$(ARDUINO)/wiring_analog.c $(ARDUINO)/wiring_digital.c \
+$(ARDUINO)/wiring_pulse.c $(ARDUINO)/wiring_serial.c \
+$(ARDUINO)/wiring_shift.c $(ARDUINO)/WInterrupts.c
+CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/Print.cpp $(ARDUINO)/WMath.cpp
+FORMAT = ihex
+
+
+# Name of this Makefile (used for "make depend").
+MAKEFILE = Makefile
+
+# Debugging format.
+# Native formats for AVR-GCC's -g are stabs [default], or dwarf-2.
+# AVR (extended) COFF requires stabs, plus an avr-objcopy run.
+DEBUG = stabs
+
+OPT = s
+
+# Place -D or -U options here
+CDEFS = -DF_CPU=$(F_CPU)
+CXXDEFS = -DF_CPU=$(F_CPU)
+
+# Place -I options here
+CINCS = -I$(ARDUINO)
+CXXINCS = -I$(ARDUINO)
+
+# Compiler flag to set the C Standard level.
+# c89 - "ANSI" C
+# gnu89 - c89 plus GCC extensions
+# c99 - ISO C99 standard (not yet fully implemented)
+# gnu99 - c99 plus GCC extensions
+CSTANDARD = -std=gnu99
+CDEBUG = -g$(DEBUG)
+CWARN = -Wall -Wstrict-prototypes
+CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
+#CEXTRA = -Wa,-adhlns=$(<:.c=.lst)
+
+CFLAGS = $(CDEBUG) $(CDEFS) $(CINCS) -O$(OPT) $(CWARN) $(CSTANDARD) $(CEXTRA)
+CXXFLAGS = $(CDEFS) $(CINCS) -O$(OPT)
+#ASFLAGS = -Wa,-adhlns=$(<:.S=.lst),-gstabs
+LDFLAGS = -lm
+
+
+# Programming support using avrdude. Settings and variables.
+AVRDUDE_PORT = $(PORT)
+AVRDUDE_WRITE_FLASH = -U flash:w:applet/$(TARGET).hex
+AVRDUDE_FLAGS = -V -F -C $(INSTALL_DIR)/hardware/tools/avrdude.conf \
+-p $(MCU) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER) \
+-b $(UPLOAD_RATE)
+
+# Program settings
+CC = $(AVR_TOOLS_PATH)/avr-gcc
+CXX = $(AVR_TOOLS_PATH)/avr-g++
+OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy
+OBJDUMP = $(AVR_TOOLS_PATH)/avr-objdump
+AR = $(AVR_TOOLS_PATH)/avr-ar
+SIZE = $(AVR_TOOLS_PATH)/avr-size
+NM = $(AVR_TOOLS_PATH)/avr-nm
+AVRDUDE = $(AVR_TOOLS_PATH)/avrdude
+REMOVE = rm -f
+MV = mv -f
+
+# Define all object files.
+OBJ = $(SRC:.c=.o) $(CXXSRC:.cpp=.o) $(ASRC:.S=.o)
+
+# Define all listing files.
+LST = $(ASRC:.S=.lst) $(CXXSRC:.cpp=.lst) $(SRC:.c=.lst)
+
+# Combine all necessary flags and optional flags.
+# Add target processor to flags.
+ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
+ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)
+ALL_ASFLAGS = -mmcu=$(MCU) -I. -x assembler-with-cpp $(ASFLAGS)
+
+
+# Default target.
+all: applet_files build sizeafter
+
+build: elf hex
+
+applet_files: $(TARGET).pde
+ # Here is the "preprocessing".
+ # It creates a .cpp file based with the same name as the .pde file.
+ # On top of the new .cpp file comes the WProgram.h header.
+ # At the end there is a generic main() function attached.
+ # Then the .cpp file will be compiled. Errors during compile will
+ # refer to this new, automatically generated, file.
+ # Not the original .pde file you actually edit...
+ test -d applet || mkdir applet
+ echo '#include "WProgram.h"' > applet/$(TARGET).cpp
+ cat $(TARGET).pde >> applet/$(TARGET).cpp
+ cat $(ARDUINO)/main.cxx >> applet/$(TARGET).cpp
+
+elf: applet/$(TARGET).elf
+hex: applet/$(TARGET).hex
+eep: applet/$(TARGET).eep
+lss: applet/$(TARGET).lss
+sym: applet/$(TARGET).sym
+
+# Program the device.
+upload: applet/$(TARGET).hex
+ $(AVRDUDE) $(AVRDUDE_FLAGS) $(AVRDUDE_WRITE_FLASH)
+
+
+ # Display size of file.
+HEXSIZE = $(SIZE) --target=$(FORMAT) applet/$(TARGET).hex
+ELFSIZE = $(SIZE) applet/$(TARGET).elf
+sizebefore:
+ @if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_BEFORE); $(HEXSIZE); echo; fi
+
+sizeafter:
+ @if [ -f applet/$(TARGET).elf ]; then echo; echo $(MSG_SIZE_AFTER); $(HEXSIZE); echo; fi
+
+
+# Convert ELF to COFF for use in debugging / simulating in AVR Studio or VMLAB.
+COFFCONVERT=$(OBJCOPY) --debugging \
+--change-section-address .data-0x800000 \
+--change-section-address .bss-0x800000 \
+--change-section-address .noinit-0x800000 \
+--change-section-address .eeprom-0x810000
+
+
+coff: applet/$(TARGET).elf
+ $(COFFCONVERT) -O coff-avr applet/$(TARGET).elf $(TARGET).cof
+
+
+extcoff: $(TARGET).elf
+ $(COFFCONVERT) -O coff-ext-avr applet/$(TARGET).elf $(TARGET).cof
+
+
+.SUFFIXES: .elf .hex .eep .lss .sym
+
+.elf.hex:
+ $(OBJCOPY) -O $(FORMAT) -R .eeprom $< $@
+
+.elf.eep:
+ -$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom="alloc,load" \
+ --change-section-lma .eeprom=0 -O $(FORMAT) $< $@
+
+# Create extended listing file from ELF output file.
+.elf.lss:
+ $(OBJDUMP) -h -S $< > $@
+
+# Create a symbol table from ELF output file.
+.elf.sym:
+ $(NM) -n $< > $@
+
+ # Link: create ELF output file from library.
+applet/$(TARGET).elf: $(TARGET).pde applet/core.a
+ $(CC) $(ALL_CFLAGS) -o $@ applet/$(TARGET).cpp -L. applet/core.a $(LDFLAGS)
+
+applet/core.a: $(OBJ)
+ @for i in $(OBJ); do echo $(AR) rcs applet/core.a $$i; $(AR) rcs applet/core.a $$i; done
+
+
+
+# Compile: create object files from C++ source files.
+.cpp.o:
+ $(CXX) -c $(ALL_CXXFLAGS) $< -o $@
+
+# Compile: create object files from C source files.
+.c.o:
+ $(CC) -c $(ALL_CFLAGS) $< -o $@
+
+
+# Compile: create assembler files from C source files.
+.c.s:
+ $(CC) -S $(ALL_CFLAGS) $< -o $@
+
+
+# Assemble: create object files from assembler source files.
+.S.o:
+ $(CC) -c $(ALL_ASFLAGS) $< -o $@
+
+
+
+# Target: clean project.
+clean:
+ $(REMOVE) applet/$(TARGET).hex applet/$(TARGET).eep applet/$(TARGET).cof applet/$(TARGET).elf \
+ applet/$(TARGET).map applet/$(TARGET).sym applet/$(TARGET).lss applet/core.a \
+ $(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d)
+
+depend:
+ if grep '^# DO NOT DELETE' $(MAKEFILE) >/dev/null; \
+ then \
+ sed -e '/^# DO NOT DELETE/,$$d' $(MAKEFILE) > \
+ $(MAKEFILE).$$$$ && \
+ $(MV) $(MAKEFILE).$$$$ $(MAKEFILE); \
+ fi
+ echo '# DO NOT DELETE THIS LINE -- make depend depends on it.' \
+ >> $(MAKEFILE); \
+ $(CC) -M -mmcu=$(MCU) $(CDEFS) $(CINCS) $(SRC) $(ASRC) >> $(MAKEFILE)
+
+.PHONY: all build elf hex eep lss sym program coff extcoff clean depend applet_files sizebefore sizeafter
--- /dev/null
+Realraum tuer instructions:
+
+1. install avr-gcc and tools:
+ $ sudo aptitude install gcc-avr avr-libc avrdude
+
+2. download arduino:
+ $ wget http://arduino.googlecode.com/files/arduino-0013-linux2.tgz
+
+3. unpack and add link:
+ $ tar -xzf arduino-0013-linux2.tgz
+ $ ln -s arduino-0013 arduino
+
+4. update Makefile variables INSTALL_DIR and PORT to your needs
+
+5. build it
+ $ make
+
+6. flash it (press reset)
+ $ make upload
--- /dev/null
+#include <avr/io.h>
+#include <avr/interrupt.h>
+
+//********************************************************************//
+
+#define HEARTBEAT_PIN 15 // blinking led indicating that system is active
+#define HEARTBEAT_DURATION 10 // *10 ms, duration of heartbeat pulse
+#define HEARTBEAT_DELAY 200 // *10 ms, 1/heartbeat-frequency
+int heartbeat_cnt = 0;
+
+#define LEDS_ON 0xFC
+#define LEDS_OFF 0x00
+
+#define LEDS_GREEN_COMMON_PIN 16
+#define LEDS_RED_COMMON_PIN 17
+#define LED_DELAY 50 // *2 ms, between led shifts
+int led_delay_cnt = 0;
+byte next_led = 0;
+
+#define LIMIT_OPENED_PIN 18 // A4: limit switch for open
+#define LIMIT_CLOSED_PIN 19 // A5: limit switch for close
+
+#define MANUAL_OPEN_PIN 12 // keys for manual open and close
+#define MANUAL_CLOSE_PIN 13 //
+
+#define IDLE 0 // close and open may be called
+#define OPENING 1 // opening, only 's' command is allowed
+#define CLOSING 2 // closing, onyl 's' command is allowed
+#define WAIT 3 // wait some time after open or close and hold last step
+#define ERROR 4 // an error occured
+
+#define CMD_OPEN 'o'
+#define CMD_CLOSE 'c'
+#define CMD_STATUS 's'
+#define CMD_RESET 'r'
+
+#define STEPPER_OFF 0x30
+byte current_state = IDLE; // current state of internal state machine
+byte next_step = 0; // step counter 0 .. 3
+#define MOVING_TIMEOUT 1600 // *2 ms, in case limit switches don't work stop and report an error
+int timeout_cnt = 0; // counts up to MOVING_TIMEOUT
+
+//********************************************************************//
+
+void init_limits()
+{
+ pinMode(LIMIT_OPENED_PIN, INPUT); // set pin to input
+ digitalWrite(LIMIT_OPENED_PIN, HIGH); // turn on pullup resistors
+
+ pinMode(LIMIT_CLOSED_PIN, INPUT); // set pin to input
+ digitalWrite(LIMIT_CLOSED_PIN, HIGH); // turn on pullup resistors
+}
+
+boolean is_opened()
+{
+ if(digitalRead(LIMIT_OPENED_PIN))
+ return false;
+
+ return true;
+}
+
+boolean is_closed()
+{
+ if(digitalRead(LIMIT_CLOSED_PIN))
+ return false;
+
+ return true;
+}
+
+//**********//
+
+void init_manual()
+{
+ pinMode(MANUAL_OPEN_PIN, INPUT); // set pin to input
+ digitalWrite(MANUAL_OPEN_PIN, HIGH); // turn on pullup resistors
+
+ pinMode(MANUAL_CLOSE_PIN, INPUT); // set pin to input
+ digitalWrite(MANUAL_CLOSE_PIN, HIGH); // turn on pullup resistors
+}
+
+boolean manual_open()
+{
+ if(digitalRead(MANUAL_OPEN_PIN))
+ return false;
+
+ return true;
+}
+
+boolean manual_close()
+{
+ if(digitalRead(MANUAL_CLOSE_PIN))
+ return false;
+
+ return true;
+}
+
+//********************************************************************//
+
+void reset_stepper()
+{
+ next_step = 0;
+ PORTB = STEPPER_OFF;
+ timeout_cnt = 0;
+}
+
+void init_stepper()
+{
+ DDRB = 0x0F; // set PortB 3:0 as output
+ reset_stepper();
+}
+
+byte step_table(byte step)
+{
+ switch(step) { // 0011 xxxx, manual keys pull-ups stay active
+ case 0: return 0x33;
+ case 1: return 0x36;
+ case 2: return 0x3C;
+ case 3: return 0x39;
+ }
+ return STEPPER_OFF;
+}
+
+//**********//
+
+void reset_leds()
+{
+ led_delay_cnt = 0;
+ next_led = 0;
+ PORTD = LEDS_OFF;
+ digitalWrite(LEDS_GREEN_COMMON_PIN, HIGH);
+ digitalWrite(LEDS_RED_COMMON_PIN, HIGH);
+}
+
+void init_leds()
+{
+ DDRD = 0xFC;
+ pinMode(LEDS_GREEN_COMMON_PIN, OUTPUT);
+ pinMode(LEDS_RED_COMMON_PIN, OUTPUT);
+ reset_leds();
+}
+
+byte led_table(byte led)
+{
+ switch(led) { // xxxx xx00, leave RxD and TxD to 0
+ case 0: return 0x04;
+ case 1: return 0x08;
+ case 2: return 0x10;
+ case 3: return 0x20;
+ case 4: return 0x40;
+ case 5: return 0x80;
+ }
+ return LEDS_OFF;
+}
+
+void leds_green()
+{
+ digitalWrite(LEDS_GREEN_COMMON_PIN, LOW);
+ digitalWrite(LEDS_RED_COMMON_PIN, HIGH);
+}
+
+void leds_red()
+{
+ digitalWrite(LEDS_GREEN_COMMON_PIN, HIGH);
+ digitalWrite(LEDS_RED_COMMON_PIN, LOW);
+}
+
+void leds_toggle()
+{
+ if(digitalRead(LEDS_GREEN_COMMON_PIN) == HIGH) {
+ digitalWrite(LEDS_GREEN_COMMON_PIN, LOW);
+ digitalWrite(LEDS_RED_COMMON_PIN, HIGH);
+ }
+ else {
+ digitalWrite(LEDS_GREEN_COMMON_PIN, HIGH);
+ digitalWrite(LEDS_RED_COMMON_PIN, LOW);
+ }
+}
+
+//**********//
+
+void start_step_timer()
+{
+ // timer 1: 2 ms, between stepper output state changes
+ TCCR1A = 0; // prescaler 1:256, WGM = 4 (CTC)
+ TCCR1B = 1<<WGM12 | 1<<CS12; //
+ OCR1A = 124; // (1+124)*256 = 32000 -> 2 ms @ 16 MHz
+ TCNT1 = 0; // reseting timer
+ TIMSK1 = 1<<OCIE1A; // enable Interrupt
+}
+
+void start_wait_timer()
+{
+ // timer1: 250 ms, minimal delay between subsequent open/close
+ TCCR1A = 0; // prescaler 1:256, WGM = 0 (normal)
+ TCCR1B = 1<<CS12; //
+ OCR1A = 15624; // (1+15624)*256 = 4000000 -> 250 ms @ 16 MHz
+ TCNT1 = 0; // reseting timer
+ TIMSK1 = 1<<OCIE1A; // enable Interrupt
+}
+
+void start_error_timer()
+{
+ // timer1: 500 ms, blinking leds with 1 Hz
+ TCCR1A = 0; // prescaler 1:256, WGM = 4 (CTC)
+ TCCR1B = 1<<WGM12 | 1<<CS12; //
+ OCR1A = 31249; // (1+31249)*256 = 8000000 -> 500 ms @ 16 MHz
+ TCNT1 = 0; // reseting timer
+ TIMSK1 = 1<<OCIE1A; // enable Interrupt
+}
+
+void stop_timer() // stop the timer
+{
+ // timer1
+ TCCR1B = 0; // no clock source
+ TIMSK1 = 0; // disable timer interrupt
+}
+
+ISR(TIMER1_COMPA_vect)
+{
+ // check if limit switch is active
+ if((current_state == OPENING && is_opened()) ||
+ (current_state == CLOSING && is_closed()))
+ {
+ stop_timer();
+ reset_leds();
+ if(current_state == OPENING)
+ leds_green();
+ else
+ leds_red();
+ PORTD = LEDS_ON;
+ current_state = WAIT;
+ start_wait_timer();
+ return;
+ }
+
+ if(current_state == OPENING || current_state == CLOSING) {
+ timeout_cnt++;
+ if(timeout_cnt >= MOVING_TIMEOUT) {
+ reset_stepper();
+ stop_timer();
+ current_state = ERROR;
+ Serial.println("Error: open/close took too long!");
+ start_error_timer();
+ leds_green();
+ PORTD = LEDS_ON;
+ }
+ }
+
+ if(current_state == OPENING) { // next step (open)
+ PORTB = step_table(next_step);
+ next_step++;
+ if(next_step >= 4)
+ next_step = 0;
+ }
+ else if(current_state == CLOSING) { // next step (close)
+ PORTB = step_table(next_step);
+ if(next_step == 0)
+ next_step = 3;
+ else
+ next_step--;
+ }
+ else if(current_state == WAIT) { // wait after last open/close finished -> idle
+ stop_timer();
+ reset_stepper();
+ current_state = IDLE;
+ return;
+ }
+ else if(current_state == ERROR) {
+ leds_toggle();
+ return;
+ }
+ else { // timer is useless stop it
+ stop_timer();
+ return;
+ }
+
+ led_delay_cnt++;
+ if(led_delay_cnt >= LED_DELAY) {
+ led_delay_cnt = 0;
+
+ PORTD = led_table(next_led);
+
+ if(current_state == OPENING) {
+ if(next_led == 0)
+ next_led = 5;
+ else
+ next_led--;
+ }
+ else if(current_state == CLOSING) {
+ next_led++;
+ if(next_led >= 6)
+ next_led = 0;
+ }
+ }
+}
+
+//********************************************************************//
+
+void reset_heartbeat()
+{
+ digitalWrite(HEARTBEAT_PIN, HIGH);
+ heartbeat_cnt = 0;
+}
+
+void heartbeat_on()
+{
+ digitalWrite(HEARTBEAT_PIN, LOW);
+}
+
+void heartbeat_off()
+{
+ digitalWrite(HEARTBEAT_PIN, HIGH);
+}
+
+void init_heartbeat()
+{
+ pinMode(HEARTBEAT_PIN, OUTPUT);
+ reset_heartbeat();
+ // timer 2: ~10 ms, timebase for heartbeat signal
+ TCCR2A = 1<<WGM21; // prescaler 1:1024, WGM = 2 (CTC)
+ TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20; //
+ OCR2A = 155; // (1+155)*1024 = 159744 -> ~10 ms @ 16 MHz
+ TCNT2 = 0; // reseting timer
+ TIMSK2 = 1<<OCIE2A; // enable Interrupt
+ heartbeat_on();
+}
+
+// while running this gets called every ~10ms
+ISR(TIMER2_COMPA_vect)
+{
+ heartbeat_cnt++;
+ if(heartbeat_cnt == HEARTBEAT_DURATION)
+ heartbeat_off();
+ else if(heartbeat_cnt >= HEARTBEAT_DELAY) {
+ heartbeat_on();
+ heartbeat_cnt = 0;
+ }
+}
+
+//********************************************************************//
+
+void reset_after_error()
+{
+ stop_timer();
+ reset_leds();
+
+ leds_red();
+ if(is_closed()) {
+ current_state = IDLE;
+ PORTD = LEDS_ON;
+ }
+ else {
+ current_state = CLOSING;
+ start_step_timer();
+ }
+ Serial.println("Ok, closing now");
+}
+
+void start_open()
+{
+ if(is_opened()) {
+ Serial.println("Already open");
+ return;
+ }
+
+ reset_stepper();
+ reset_leds();
+ leds_green();
+ current_state = OPENING;
+ start_step_timer();
+ Serial.println("Ok");
+}
+
+void start_close()
+{
+ if(is_closed()) {
+ Serial.println("Already closed");
+ return;
+ }
+
+ reset_stepper();
+ reset_leds();
+ leds_red();
+ current_state = CLOSING;
+ start_step_timer();
+ Serial.println("Ok");
+}
+
+void print_status()
+{
+ Serial.print("Status: ");
+ if(is_opened())
+ Serial.print("opened");
+ else if(is_closed())
+ Serial.print("closed");
+ else
+ Serial.print("<->");
+
+ switch(current_state) {
+ case IDLE: Serial.println(", idle"); break;
+ case OPENING: Serial.println(", opening"); break;
+ case CLOSING: Serial.println(", closing"); break;
+ case WAIT: Serial.println(", waiting"); break;
+ default: Serial.println(", <undefined state>"); break;
+ }
+
+}
+
+//**********//
+
+void setup()
+{
+ init_limits();
+ init_stepper();
+ init_leds();
+ init_heartbeat();
+
+ Serial.begin(9600);
+
+ current_state = IDLE;
+
+ // make sure door is locked after reset
+ leds_red();
+ if(is_closed())
+ PORTD = LEDS_ON;
+ else {
+ current_state = CLOSING;
+ start_step_timer();
+ }
+}
+
+void loop()
+{
+ if(Serial.available()) {
+ char command = Serial.read();
+
+ if(current_state == ERROR && command != CMD_RESET) {
+ Serial.println("Error: last open/close operation took to long!");
+ }
+ else if (command == CMD_RESET) {
+ reset_after_error();
+ }
+ else if (command == CMD_OPEN) {
+ if(current_state == IDLE)
+ start_open();
+ else
+ Serial.println("Error: Operation in progress");
+ }
+ else if (command == CMD_CLOSE) {
+ if(current_state == IDLE)
+ start_close();
+ else
+ Serial.println("Error: Operation in progress");
+ }
+ else if (command == CMD_STATUS)
+ print_status();
+ else
+ Serial.println("Error: unknown command");
+ }
+ if(manual_open() && !is_opened() && current_state == IDLE) {
+ Serial.println("open forced manually");
+ start_open();
+ }
+ if(manual_close() && !is_closed() && current_state == IDLE) {
+ Serial.println("close forced manually");
+ start_close();
+ }
+ if (current_state == IDLE) {
+ if(is_opened()) {
+ leds_green();
+ PORTD = LEDS_ON;
+ }
+ if(is_closed()) {
+ leds_red();
+ PORTD = LEDS_ON;
+ }
+ }
+}
--- /dev/null
+/* mifare-tool - a small command-line tool for librfid mifare testing
+ *
+ * (C) 2006 by Harald Welte <laforge@gnumonks.org>
+ *
+ * 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 <signal.h>
+
+#include <librfid/rfid.h>
+#include <librfid/rfid_scan.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>
+
+//#include <librfid/rfid_access_mifare_classic.h>
+
+struct rfid_reader_handle *rh = NULL;
+struct rfid_layer2_handle *l2h = NULL;
+struct rfid_protocol_handle *ph = NULL;
+
+
+void sigHandler(int sig)
+{
+ printf("sig handler called\n");
+
+/* rfid_protocol_close(ph); */
+/* rfid_protocol_fini(ph); */
+
+ rfid_layer2_close(l2h);
+ rfid_layer2_fini(l2h);
+
+ rfid_reader_close(rh);
+ exit(0);
+}
+
+int l2_init(int layer2)
+{
+ int rc;
+
+ l2h = rfid_layer2_init(rh, layer2);
+ if (!l2h) {
+ fprintf(stderr, "error during layer2(%d)_init (0=14a,1=14b,3=15)\n",layer2);
+ return -1;
+ }
+
+ rc = rfid_layer2_open(l2h);
+ if (rc < 0) {
+ fprintf(stderr, "error during layer2_open\n");
+ return rc;
+ }
+
+ return 0;
+}
+
+int l3_init(int protocol)
+{
+ 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;
+ }
+
+ return 0;
+}
+
+static int mifare_cl_auth(unsigned char *key, int page)
+{
+ int rc;
+
+ rc = mfcl_set_key(ph, key);
+ if (rc < 0) {
+ fprintf(stderr, "key format error\n");
+ return rc;
+ }
+ rc = mfcl_auth(ph, RFID_CMD_MIFARE_AUTH1A, page);
+ if (rc < 0) {
+ fprintf(stderr, "mifare auth error\n");
+ return rc;
+ } else
+// printf("mifare auth succeeded!\n");
+
+ return 0;
+}
+
+static void mifare_l3(void)
+{
+ while (l2_init(RFID_LAYER2_ISO14443A) < 0) ;
+
+// printf("ISO14443-3A anticollision succeeded\n");
+
+// while (l3_init(RFID_PROTOCOL_MIFARE_CLASSIC) < 0) ;
+
+// printf("Mifare card available\n");
+}
+
+void print_hex(const unsigned char* buffer, int length)
+{
+ int i;
+
+ if(length <= 0) return;
+ for(i=0; i<length; ++i) {
+ printf("0x%02X ", buffer[i]);
+ if(i && !((i+1)%8)) printf(" ");
+ if(i && !((i+1)%16)) printf("\n");
+ }
+}
+
+int main(int argc, char **argv)
+{
+ int len, rc, c, option_index = 0;
+ unsigned int page,uid,uid_len;
+ //char key[MIFARE_CL_KEY_LEN];
+ //char buf[MIFARE_CL_PAGE_SIZE];
+
+ (void) signal(SIGHUP, sigHandler);
+ (void) signal(SIGINT, sigHandler);
+ (void) signal(SIGTERM, sigHandler);
+
+/* init */
+
+ //memcpy(key, MIFARE_CL_KEYA_DEFAULT_INFINEON, MIFARE_CL_KEY_LEN);
+
+// printf("initializing librfid\n");
+ rfid_init();
+
+ rh = rfid_reader_open(NULL, RFID_READER_OPENPCD);
+ if (!rh) {
+ fprintf(stderr, "No OpenPCD found\n");
+ exit(1);
+ }
+
+/* reading serial */
+
+ page = 0; //page 0
+
+ //len = MIFARE_CL_PAGE_SIZE;
+ mifare_l3();
+/* if (mifare_cl_auth(key, page) < 0) */
+/* exit(1); */
+
+ uid_len=sizeof(uid);
+ uid=0;
+ if(rfid_layer2_getopt(l2h,RFID_OPT_LAYER2_UID,&uid,&uid_len)>=0)
+ printf("UID=%08X (len=%u)\n",uid,uid_len);
+ fflush(stdout);
+
+// rfid_layer2_close(l2h);
+// rfid_layer2_fini(l2h);
+
+ rfid_reader_close(rh);
+ exit(0);
+}
+
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+my $fh;
+
+my $keys;
+my %good;
+my $status = 'c';
+
+open $keys,'/flash/realraum/keys';
+while (<$keys>)
+{
+ my ($code,$comment) = split /\s/,$_,2;
+ $good{$code}=$comment;
+}
+
+while (sleep 1)
+{
+ open $fh,'/flash/realraum/a.out 0 2>&1 |';
+ while (<$fh>)
+ {
+ next unless /UID/;
+ my ($id) = /UID=(\S+)\s+/;
+ if ($good{$id})
+ {
+ my $newstat;
+ if ($status eq 'o')
+ {
+ $newstat='c';
+
+ } else {
+ $newstat = 'o';
+ }
+ print "$newstat: $good{$id}";
+ system ( "echo -n $newstat > /dev/ttyUSB0");
+ $status = $newstat;
+ } else {
+ print "boese\n";
+ }
+ }
+
+}
--- /dev/null
+#!/usr/bin/perl
+
+use strict;
+