libnfc  1.4.2
iso14443-subr.c
Go to the documentation of this file.
00001 /*-
00002  * Public platform independent Near Field Communication (NFC) library
00003  * 
00004  * Copyright (C) 2009, Roel Verdult
00005  * 
00006  * This program is free software: you can redistribute it and/or modify it
00007  * under the terms of the GNU Lesser General Public License as published by the
00008  * Free Software Foundation, either version 3 of the License, or (at your
00009  * option) any later version.
00010  * 
00011  * This program is distributed in the hope that it will be useful, but WITHOUT
00012  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
00014  * more details.
00015  *
00016  * You should have received a copy of the GNU Lesser General Public License
00017  * along with this program.  If not, see <http://www.gnu.org/licenses/>
00018  */
00019 
00025 #ifdef HAVE_CONFIG_H
00026 #  include "config.h"
00027 #endif // HAVE_CONFIG_H
00028 
00029 #include <stdio.h>
00030 
00031 #include <nfc/nfc.h>
00032 
00033 void
00034 iso14443a_crc (byte_t * pbtData, size_t szLen, byte_t * pbtCrc)
00035 {
00036   byte_t  bt;
00037   uint32_t wCrc = 0x6363;
00038 
00039   do {
00040     bt = *pbtData++;
00041     bt = (bt ^ (byte_t) (wCrc & 0x00FF));
00042     bt = (bt ^ (bt << 4));
00043     wCrc = (wCrc >> 8) ^ ((uint32_t) bt << 8) ^ ((uint32_t) bt << 3) ^ ((uint32_t) bt >> 4);
00044   } while (--szLen);
00045 
00046   *pbtCrc++ = (byte_t) (wCrc & 0xFF);
00047   *pbtCrc = (byte_t) ((wCrc >> 8) & 0xFF);
00048 }
00049 
00050 void
00051 iso14443a_crc_append (byte_t * pbtData, size_t szLen)
00052 {
00053   iso14443a_crc (pbtData, szLen, pbtData + szLen);
00054 }
00055 
00056 byte_t *
00057 iso14443a_locate_historical_bytes(byte_t * pbtAts, size_t szAts, size_t * pszTk)
00058 {
00059   if (szAts) {
00060     size_t offset = 1;
00061     if (pbtAts[0] & 0x10) { // TA
00062       offset++;
00063     }
00064     if (pbtAts[0] & 0x20) { // TB
00065       offset++;
00066     }
00067     if (pbtAts[0] & 0x40) { // TC
00068       offset++;
00069     }
00070     if (szAts > offset) {
00071       *pszTk = (szAts-offset);
00072       return (pbtAts+offset);
00073     }
00074   }
00075   *pszTk = 0;
00076   return NULL;
00077 }