From e3d49c4785528982b87e22628080e5447713913b Mon Sep 17 00:00:00 2001 From: laforge Date: Fri, 8 Feb 2008 15:12:15 +0000 Subject: python update (Kushal Das) git-svn-id: https://svn.gnumonks.org/trunk/librfid@2078 e0336214-984f-0b4b-a45f-81c69e1f0ede --- python/openpcd.c | 392 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 392 insertions(+) create mode 100644 python/openpcd.c (limited to 'python/openpcd.c') diff --git a/python/openpcd.c b/python/openpcd.c new file mode 100644 index 0000000..4fb086c --- /dev/null +++ b/python/openpcd.c @@ -0,0 +1,392 @@ +/*************************************************************************/ +/* */ +/* Mifare support for accessing RFID cards with OpenPCD RFID reader */ +/* in WIN32 - see http://www.openpcd.org */ +/* */ +/* 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. */ +/* */ +/*************************************************************************/ + +#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; +} + +void Sleep(unsigned int ms ) { + usleep(ms*1000); +} + +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]; +} -- cgit v1.2.3