From 64b0ed9cf4f26a0efb85f7547821409ca2e97a9d Mon Sep 17 00:00:00 2001 From: meri Date: Wed, 2 May 2007 01:48:44 +0000 Subject: updated win32 support for MINGW32-compiler/cross-compiler git-svn-id: https://svn.gnumonks.org/trunk/librfid@1991 e0336214-984f-0b4b-a45f-81c69e1f0ede --- win32/Makefile.am | 15 +++ win32/openpcd.c | 355 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ win32/openpcd.def | 15 +++ win32/openpcd.h | 174 ++++++++++++++++++++++++++ win32/openpcd.lib | Bin 0 -> 4628 bytes 5 files changed, 559 insertions(+) create mode 100644 win32/Makefile.am create mode 100644 win32/openpcd.c create mode 100644 win32/openpcd.def create mode 100644 win32/openpcd.h create mode 100755 win32/openpcd.lib diff --git a/win32/Makefile.am b/win32/Makefile.am new file mode 100644 index 0000000..f565f1f --- /dev/null +++ b/win32/Makefile.am @@ -0,0 +1,15 @@ +LIBVERSION= 0:0:0 + +noinst_HEADERS = openpcd.h +noinst_DATA = openpcd.dll + +INCLUDES = -I$(top_srcdir)/include +LIBRFID_DIR = $(top_builddir)/src/.libs/ +CLEANFILES = $(noinst_DATA) + +.c.o: + $(CC) $(CFLAGS) $(INCLUDES) -c $< -o $@ + +.o.dll: + $(CC) -mno-cygwin --add-stdcall-alias -shared -o $@ -L$(LIBRFID_DIR) $< -lrfid -lwinmm -Wl,-no-undefined -Wl,--entry,__cygwin_noncygwin_dll_entry@12 + $(STRIP) --strip-unneeded $@ diff --git a/win32/openpcd.c b/win32/openpcd.c new file mode 100644 index 0000000..21daf6e --- /dev/null +++ b/win32/openpcd.c @@ -0,0 +1,355 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define BUILD_DLL +#include "openpcd.h" + +#define LIBMIFARE_MAGIC 0xDEADBEEF + +struct openpcd_state +{ + unsigned int magic; + unsigned int cl_auth; + struct rfid_reader_handle *rh; + struct rfid_layer2_handle *l2h; + struct rfid_protocol_handle *ph; + unsigned char key[MIFARE_CL_KEY_LEN]; + unsigned int uid; +} openpcd_state; + +int openpcd_cl_auth(struct openpcd_state* state ,int page) +{ + int rc; + + if(!state || page<=0 || page>MIFARE_CL_PAGE_MAX ) + return PCDERROR_INVALID_PARAMETER; + + if(!state->ph) + return PCDERROR_CLOSED; + + rc = mfcl_set_key(state->ph, state->key); + if (rc < 0) + return PCDERROR_KEY_FORMAT; + + rc = mfcl_auth(state->ph, state->cl_auth, page); + + return rc<0 ? PCDERROR_KEY_AUTH : PCDERROR_NONE; +} + +EXPORT int EXPORT_CONVENTION openpcd_set_key(MIFARE_HANDLE handle,unsigned int key_id,const void* key) +{ + struct openpcd_state *state; + + if(!handle) + return PCDERROR_INVALID_PARAMETER; + state=(struct openpcd_state*)handle; + + switch(key_id) + { + case PCDAUTH_KEYID_1A: + state->cl_auth=RFID_CMD_MIFARE_AUTH1A; + break; + case PCDAUTH_KEYID_1B: + state->cl_auth=RFID_CMD_MIFARE_AUTH1B; + break; + default: + return PCDERROR_INVALID_PARAMETER; + } + + memcpy(state->key,key,MIFARE_CL_KEY_LEN); + + return PCDERROR_NONE; +} + +EXPORT int EXPORT_CONVENTION openpcd_select_card(MIFARE_HANDLE handle) +{ + int res; + struct openpcd_state *state; + + if(!handle) + return PCDERROR_INVALID_PARAMETER; + state=(struct openpcd_state*)handle; + + state->l2h = rfid_layer2_init(state->rh,RFID_LAYER2_ISO14443A); + if(!state->l2h) + res=PCDERROR_LAYER2_INIT; + else + { + if( rfid_layer2_open(state->l2h)>=0 ) + { + state->ph = rfid_protocol_init(state->l2h,RFID_PROTOCOL_MIFARE_CLASSIC); + + if(state->ph) + { + if(rfid_protocol_open(state->ph)>=0) + return PCDERROR_NONE; + + rfid_protocol_fini(state->ph); + state->ph=NULL; + + res=PCDERROR_LAYER3_OPEN; + } + else + res=PCDERROR_LAYER3_INIT; + + rfid_layer2_close(state->l2h); + } + else + res=PCDERROR_LAYER2_OPEN; + } + + rfid_layer2_fini(state->l2h); + state->l2h=NULL; + + return res; +} + +EXPORT int EXPORT_CONVENTION openpcd_deselect_card(MIFARE_HANDLE handle) +{ + struct openpcd_state *state; + + if(!handle) + return PCDERROR_INVALID_PARAMETER; + state=(struct openpcd_state*)handle; + + if(state->ph) + { + rfid_protocol_close(state->ph); + rfid_protocol_fini(state->ph); + rfid_layer2_close(state->l2h); + rfid_layer2_fini(state->l2h); + + state->ph=NULL; + state->l2h=NULL; + state->uid=0; + + return PCDERROR_NONE; + } + else + return PCDERROR_CLOSED; +} + +EXPORT int EXPORT_CONVENTION openpcd_get_card_id(MIFARE_HANDLE handle,unsigned int *uid) +{ + unsigned int uid_len; + struct openpcd_state *state; + + if(!handle || !uid) + return PCDERROR_INVALID_PARAMETER; + state=(struct openpcd_state*)handle; + + if(state->ph) + { + uid_len=sizeof(*uid); + if(rfid_layer2_getopt(state->l2h,RFID_OPT_LAYER2_UID,uid,&uid_len)) + return PCDERROR_INVALID_PARAMETER; + else + return uid_len==4 ? PCDERROR_NONE:PCDERROR_READ_FAILED; + } + else + return PCDERROR_CLOSED; +} + +EXPORT int EXPORT_CONVENTION openpcd_open_reader(MIFARE_HANDLE *handle) +{ + struct rfid_reader_handle *rh; + struct openpcd_state *state; + + if(!handle) + return PCDERROR_INVALID_PARAMETER; + + rh = rfid_reader_open(NULL, RFID_READER_OPENPCD); + if(!rh) + return PCDERROR_NO_READER; + + state=(struct openpcd_state*)malloc(sizeof(*state)); + if(state) + { + memset(state,0,sizeof(*state)); + state->magic=LIBMIFARE_MAGIC; + state->rh=rh; + state->cl_auth=RFID_CMD_MIFARE_AUTH1A; + memset(state->key,0xFF,sizeof(state->key)); + + // do initial reset + openpcd_reset_reader((MIFARE_HANDLE)state); + Sleep(1500); + // reopen + state->rh = rfid_reader_open(NULL, RFID_READER_OPENPCD); + + *handle=(MIFARE_HANDLE)state; + + return PCDERROR_NONE; + } + else + { + rfid_reader_close(rh); + return PCDERROR_OUT_OF_MEMORY; + } +} + +EXPORT int EXPORT_CONVENTION openpcd_close_reader(MIFARE_HANDLE handle) +{ + struct openpcd_state *state; + + if(!handle) + return PCDERROR_INVALID_PARAMETER; + state=(struct openpcd_state*)handle; + + openpcd_deselect_card(handle); + + openpcd_reset_reader(handle); + Sleep(500); + + state->magic=0; + rfid_reader_close(state->rh); + free(state); + + return PCDERROR_NONE; +} + +EXPORT int EXPORT_CONVENTION openpcd_read(MIFARE_HANDLE handle,int page, void* data, int len) +{ + int res; + unsigned int count; + unsigned char buf[MIFARE_CL_PAGE_SIZE]; + struct openpcd_state *state; + + if( !handle || !buf || page<0 || page>MIFARE_CL_PAGE_MAX || len<=0 || len>sizeof(buf)) + return PCDERROR_INVALID_PARAMETER; + + state=(struct openpcd_state*)handle; + if ( (res=openpcd_cl_auth(state,page)) < 0) + return res; + + count = sizeof(buf); + res = rfid_protocol_read(state->ph, page, buf, &count); + if(res>=0) + memcpy(data,buf,len); + + if ( res<0 ) + return PCDERROR_READ_FAILED; + else + return count; +} + +EXPORT int EXPORT_CONVENTION openpcd_write(MIFARE_HANDLE handle,int page,const void *data,int len) +{ + int res; + unsigned char buf[16]; + struct openpcd_state *state; + + if( !handle || !buf || page<0 || page>MIFARE_CL_PAGE_MAX || len<=0 || len>sizeof(buf)) + return PCDERROR_INVALID_PARAMETER; + + state=(struct openpcd_state*)handle; + if ( (res=openpcd_cl_auth(state,page)) < 0) + return res; + + memcpy(buf,data,len); + memset(&buf[len],0,sizeof(buf)-len); + + res = rfid_protocol_write(state->ph, page, buf, sizeof(buf)); + + return (res<0 && res!=-101) ? PCDERROR_WRITE_FAILED : len; +} + +EXPORT int EXPORT_CONVENTION openpcd_get_api_version(MIFARE_HANDLE handle, unsigned int *version) +{ + unsigned char b; + struct openpcd_state *state; + + if( !handle || !version ) + return PCDERROR_INVALID_PARAMETER; + state=(struct openpcd_state*)handle; + + b=0; + + if(state->rh->reader->get_api_version(state->rh,&b)<0) + return PCDERROR_READER_VERSION; + else + { + *version=b; + return PCDERROR_NONE; + } +} + +EXPORT int EXPORT_CONVENTION openpcd_reset_reader(MIFARE_HANDLE handle) +{ + struct openpcd_state *state; + + if( !handle ) + return PCDERROR_INVALID_PARAMETER; + state=(struct openpcd_state*)handle; + + return (state->rh->reader->reset(state->rh)<0) ? PCDERROR_WRITE_FAILED : PCDERROR_NONE; +} + +EXPORT int EXPORT_CONVENTION openpcd_get_environment( + MIFARE_HANDLE handle, + unsigned char count, + unsigned char* data + ) +{ + struct openpcd_state *state; + + if( !handle ) + return PCDERROR_INVALID_PARAMETER; + state=(struct openpcd_state*)handle; + + return (state->rh->reader->get_environment(state->rh,count,data)<0) ? PCDERROR_READ_FAILED : PCDERROR_NONE; +} + +EXPORT int EXPORT_CONVENTION openpcd_set_environment( + MIFARE_HANDLE handle, + unsigned char count, + const unsigned char* data) +{ + struct openpcd_state *state; + + if( !handle ) + return PCDERROR_INVALID_PARAMETER; + state=(struct openpcd_state*)handle; + + return (state->rh->reader->set_environment(state->rh,count,data)<0) ? PCDERROR_WRITE_FAILED : PCDERROR_NONE; +} + +EXPORT char* EXPORT_CONVENTION openpcd_get_error_text(int error) +{ + const static char* msg[]={ + "PCDERROR_NONE", // 0 + "PCDERROR_INVALID_PARAMETER", // -1 + "PCDERROR_KEY_FORMAT", // -2 + "PCDERROR_KEY_AUTH", // -3 + "PCDERROR_NO_CARD_FOUND", // -4 + "PCDERROR_LAYER2_INIT", // -5 + "PCDERROR_LAYER2_OPEN", // -6 + "PCDERROR_LAYER3_INIT", // -7 + "PCDERROR_LAYER3_OPEN", // -8 + "PCDERROR_SELECT", // -9 + "PCDERROR_READ_FAILED", // -10 + "PCDERROR_WRITE_FAILED", // -11 + "PCDERROR_CLOSED", // -12 + "PCDERROR_NO_READER", // -13 + "PCDERROR_OUT_OF_MEMORY", // -14 + "PCDERROR_READER_VERSION" // -15 + }; + const int count=sizeof(msg)/sizeof(msg[0]); + + if(error>0) + error=0; + else + error=-error; + + return (error>=count) ? "PCDERROR_UNKNOWN" : (char*)msg[error]; +} diff --git a/win32/openpcd.def b/win32/openpcd.def new file mode 100644 index 0000000..2ba78d7 --- /dev/null +++ b/win32/openpcd.def @@ -0,0 +1,15 @@ +LIBRARY openpcd.dll +EXPORTS + openpcd_open_reader@4 + openpcd_close_reader@4 + openpcd_select_card@4 + openpcd_deselect_card@4 + openpcd_read@16 + openpcd_write@16 + openpcd_get_card_id@8 + openpcd_set_key@12 + openpcd_get_error_text@4 + openpcd_get_api_version@8 + openpcd_get_environment@12 + openpcd_set_environment@12 + openpcd_reset_reader@4 diff --git a/win32/openpcd.h b/win32/openpcd.h new file mode 100644 index 0000000..6852649 --- /dev/null +++ b/win32/openpcd.h @@ -0,0 +1,174 @@ +/*************************************************************************/ +/* */ +/* Mifare support for accessing RFID cards with Infratec RFID reader */ +/* */ +/* Copyright (C) 2007 Milosch Meriac */ +/* */ +/* Redistribution and use in source and binary forms, with or without */ +/* modification, are permitted provided that the following conditions are*/ +/* met: */ +/* */ +/* Redistributions of source code must retain the above copyright notice,*/ +/* this list of conditions and the following disclaimer. */ +/* Redistributions in binary form must reproduce the above copyright */ +/* notice, this list of conditions and the following disclaimer in the */ +/* documentation and/or other materials provided with the distribution. */ +/* */ +/* The name of the author may not be used to endorse or promote products */ +/* derived from this software without specific prior written permission. */ +/* */ +/* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR */ +/* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED */ +/* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE*/ +/* DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, */ +/* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES */ +/* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR */ +/* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) */ +/* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, */ +/* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING */ +/* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE */ +/* POSSIBILITY OF SUCH DAMAGE. */ +/* */ +/*************************************************************************/ + +#ifndef __OPENPCD_H__ +#define __OPENPCD_H__ + +#ifdef __cplusplus +extern "C" { +#endif/*__cplusplus*/ + +#define EXPORT_CONVENTION __stdcall +#ifdef BUILD_DLL +/* DLL export */ +#define EXPORT __declspec(dllexport) +#else +/* EXE import */ +#define EXPORT __declspec(dllimport) +#endif /*BUILD_DLL*/ + +#define PCDERROR_NONE 0 +#define PCDERROR_INVALID_PARAMETER -1 +#define PCDERROR_KEY_FORMAT -2 +#define PCDERROR_KEY_AUTH -3 +#define PCDERROR_NO_CARD_FOUND -4 +#define PCDERROR_LAYER2_INIT -5 +#define PCDERROR_LAYER2_OPEN -6 +#define PCDERROR_LAYER3_INIT -7 +#define PCDERROR_LAYER3_OPEN -8 +#define PCDERROR_SELECT -9 +#define PCDERROR_READ_FAILED -10 +#define PCDERROR_WRITE_FAILED -11 +#define PCDERROR_CLOSED -12 +#define PCDERROR_NO_READER -13 +#define PCDERROR_OUT_OF_MEMORY -14 +#define PCDERROR_READER_VERSION -15 + +#define PCDAUTH_KEY_LENGTH 6 +#define PCDAUTH_KEYID_1A 0 +#define PCDAUTH_KEYID_1B 1 + +typedef void* MIFARE_HANDLE; + +/*************************************************************************/ +/* */ +/* Six steps for reading/writing to MIFARE cards */ +/* */ +/*************************************************************************/ + +/* Step 1. open reader + + supply the address of your handle variable to retrieve a handle + to the current reader. + */ +EXPORT int EXPORT_CONVENTION openpcd_open_reader(MIFARE_HANDLE *handle); + +/* Step 2. set MIFARE classic key + + if your key differs from the default Infineon key (6*0xFF), you can + supply a different key here. The key size is PCDAUTH_KEY_LENGTH bytes. + You can chose to set key_id to PCDAUTH_KEYID_1A or *_1B. + */ +EXPORT int EXPORT_CONVENTION openpcd_set_key(MIFARE_HANDLE handle,unsigned int key_id,const void* key); + +/* Step 3. select card + + start the anticollosion to select a card in the reader field - retry if + it fails. Currently supports only on card in the readerv field. + */ +EXPORT int EXPORT_CONVENTION openpcd_select_card(MIFARE_HANDLE handle); + +/* Step 4. read/write card + + read, write from the selected card - specify the page and supply up to + 16 bytes of payload + */ +EXPORT int EXPORT_CONVENTION openpcd_read(MIFARE_HANDLE handle,int page, void* data, int len); +EXPORT int EXPORT_CONVENTION openpcd_write(MIFARE_HANDLE handle,int page,const void *data,int len); + +/* Step 5. deselect card when done + */ +EXPORT int EXPORT_CONVENTION openpcd_deselect_card(MIFARE_HANDLE handle); + +/* Step 6. close reader after deselected card + */ +EXPORT int EXPORT_CONVENTION openpcd_close_reader(MIFARE_HANDLE handle); + + +/*************************************************************************/ +/* */ +/* Support functions */ +/* */ +/*************************************************************************/ + +/* openpcd_get_error_text: + + Used for converting the error code into a string + */ +EXPORT char* EXPORT_CONVENTION openpcd_get_error_text(int error); + + +/* openpcd_get_card_id: + + Get the card id of a selected RFID card + */ +EXPORT int EXPORT_CONVENTION openpcd_get_card_id(MIFARE_HANDLE handle,unsigned int *uid); + +/* openpcd_get_api_version: + + Get the USB api version of the reader + */ +EXPORT int EXPORT_CONVENTION openpcd_get_api_version(MIFARE_HANDLE handle,unsigned int *version); + +/* openpcd_reset_reader: + + Reset the attached reader + */ +EXPORT int EXPORT_CONVENTION openpcd_reset_reader(MIFARE_HANDLE handle); + +/* openpcd_get_environment + + Store the given data to the nonvolatile reader flash + Returns read data count at index or error code + */ +EXPORT int EXPORT_CONVENTION openpcd_get_environment( + MIFARE_HANDLE handle, + unsigned char count, + unsigned char* data +); + +/* openpcd_set_environment + + Read data from nonvolatile reader flash + Returns written data count at index or error code + */ +EXPORT int EXPORT_CONVENTION openpcd_set_environment( + MIFARE_HANDLE handle, + unsigned char count, + const unsigned char* data +); + +#ifdef __cplusplus +} +#endif/*__cplusplus*/ +#endif/*__OPENPCD_H__*/ diff --git a/win32/openpcd.lib b/win32/openpcd.lib new file mode 100755 index 0000000..017d201 Binary files /dev/null and b/win32/openpcd.lib differ -- cgit v1.2.3