summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSunil Jogi <sunil.jogi@nxp.com>2012-01-12 13:47:03 -0800
committerMartijn Coenen <maco@google.com>2012-04-02 10:35:05 -0700
commit40734e7599249717860f7aeabda494e1bcd86ffe (patch)
tree751c039f155c81680dfa35ce81eef53046a506ae
parenteb6da80b266a263350769a0e5629f4089aad32bb (diff)
downloadexternal_libnfc-nxp-40734e7599249717860f7aeabda494e1bcd86ffe.zip
external_libnfc-nxp-40734e7599249717860f7aeabda494e1bcd86ffe.tar.gz
external_libnfc-nxp-40734e7599249717860f7aeabda494e1bcd86ffe.tar.bz2
Mifare readonly support.
This patch requires changes done in following projects submited as patches: 1. packages/apps/Nfc 2. frameworks/base Change-Id: I9036309d82dd897e77f6bc14c30fbde255bf955c
-rw-r--r--src/phFriNfc_MapTools.c12
-rw-r--r--src/phFriNfc_MifareStdMap.c392
-rw-r--r--src/phFriNfc_MifareStdMap.h21
-rw-r--r--src/phFriNfc_NdefMap.h9
-rw-r--r--src/phLibNfc.h9
-rw-r--r--src/phLibNfc_ndef_raw.c33
-rw-r--r--src/phLibNfc_ndef_raw.h1
7 files changed, 455 insertions, 22 deletions
diff --git a/src/phFriNfc_MapTools.c b/src/phFriNfc_MapTools.c
index 2283473..2e05d33 100644
--- a/src/phFriNfc_MapTools.c
+++ b/src/phFriNfc_MapTools.c
@@ -99,6 +99,18 @@ NFCSTATUS phFriNfc_MapTool_SetCardState(phFriNfc_NdefMap_t *NdefMap,
PH_NDEFMAP_CARD_STATE_INVALID)?
NdefMap->CardState:
PH_NDEFMAP_CARD_STATE_READ_WRITE);
+ if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD ||
+ NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)
+ {
+ if(NdefMap->StdMifareContainer.ReadOnlySectorIndex &&
+ NdefMap->StdMifareContainer.SectorTrailerBlockNo == NdefMap->StdMifareContainer.currentBlock )
+ {
+ NdefMap->CardState = (uint8_t)((NdefMap->CardState ==
+ PH_NDEFMAP_CARD_STATE_INVALID)?
+ NdefMap->CardState:
+ PH_NDEFMAP_CARD_STATE_READ_ONLY);
+ }
+ }
break;
default:
diff --git a/src/phFriNfc_MifareStdMap.c b/src/phFriNfc_MifareStdMap.c
index 053fd55..3e8b6db 100644
--- a/src/phFriNfc_MifareStdMap.c
+++ b/src/phFriNfc_MifareStdMap.c
@@ -38,6 +38,8 @@
#include <phFriNfc_MapTools.h>
+#include <phFriNfc_MifStdFormat.h>
+
/*! \ingroup grp_file_attributes
* \name NDEF Mapping
*
@@ -409,6 +411,11 @@ static void phFriNfc_MifStd1k_H_BlkChk(phFriNfc_NdefMap_t *NdefMap,
uint8_t SectorID,
uint8_t *callbreak);
+static uint8_t phFriNfc_MifStd_H_GetSectorTrailerBlkNo(uint8_t SectorID );
+static NFCSTATUS phFriNfc_MifStd_H_ProSectorTrailorAcsBits(phFriNfc_NdefMap_t *NdefMap);
+static NFCSTATUS phFriNfc_MifStd_H_WrSectorTrailorBlock(phFriNfc_NdefMap_t *NdefMap);
+static NFCSTATUS phFriNfc_MifStd_H_ProWrSectorTrailor(phFriNfc_NdefMap_t *NdefMap);
+
/*@}*/
/**
* \name Mifare Standard Mapping - Constants.
@@ -534,6 +541,12 @@ NFCSTATUS phFriNfc_MifareStdMap_H_Reset(phFriNfc_NdefMap_t *NdefMap)
NdefMap->StdMifareContainer.WrLength = PH_FRINFC_MIFARESTD_VAL1;
NdefMap->StdMifareContainer.ChkNdefCompleteFlag = PH_FRINFC_MIFARESTD_FLAG0;
+
+ NdefMap->StdMifareContainer.ReadOnlySectorIndex = PH_FRINFC_MIFARESTD_FLAG0;
+
+ NdefMap->StdMifareContainer.TotalNoSectors = PH_FRINFC_MIFARESTD_FLAG0;
+
+ NdefMap->StdMifareContainer.SectorTrailerBlockNo = PH_FRINFC_MIFARESTD_FLAG0;
}
return status;
@@ -894,7 +907,6 @@ void phFriNfc_MifareStdMap_Process( void *Context,
NdefMap = (phFriNfc_NdefMap_t *)Context;
-
if((Status & PHNFCSTBLOWER) == (NFCSTATUS_SUCCESS & PHNFCSTBLOWER))
{
switch(NdefMap->State)
@@ -1149,6 +1161,18 @@ void phFriNfc_MifareStdMap_Process( void *Context,
NdefMap->StdMifareContainer.FirstReadFlag = PH_FRINFC_MIFARESTD_FLAG0;
Status = phFriNfc_MifStd_H_AuthSector(NdefMap);
}
+ else if((NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD ||
+ NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD) &&
+ (NdefMap->StdMifareContainer.ReadOnlySectorIndex &&
+ NdefMap->StdMifareContainer.SectorTrailerBlockNo == NdefMap->StdMifareContainer.currentBlock))
+ {
+ NdefMap->StdMifareContainer.ReadOnlySectorIndex =
+ PH_FRINFC_MIFARESTD_FLAG0;
+ NdefMap->StdMifareContainer.SectorTrailerBlockNo =
+ PH_FRINFC_MIFARESTD_FLAG0;
+ NdefMap->StdMifareContainer.currentBlock = PH_FRINFC_MIFARESTD_FLAG0;
+ Status = NFCSTATUS_FAILED;
+ }
else
{
Status = ((((NdefMap->Offset == PH_FRINFC_NDEFMAP_SEEK_CUR) &&
@@ -1163,6 +1187,34 @@ void phFriNfc_MifareStdMap_Process( void *Context,
PH_FRINFC_MIFARESTD_FLAG0);
break;
+ case PH_FRINFC_NDEFMAP_STATE_RD_SEC_ACS_BIT:
+ Status = phFriNfc_MifStd_H_ProSectorTrailorAcsBits(NdefMap);
+ CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)?
+ PH_FRINFC_MIFARESTD_FLAG1:
+ PH_FRINFC_MIFARESTD_FLAG0);
+ break;
+
+ case PH_FRINFC_NDEFMAP_STATE_WRITE_SEC:
+ /* The first NDEF sector is already made read only,
+ set card state to read only and proceed*/
+ if(NdefMap->CardState != PH_NDEFMAP_CARD_STATE_READ_ONLY)
+ {
+ Status = phFriNfc_MapTool_SetCardState(NdefMap, NdefMap->TLVStruct.BytesRemainLinTLV);
+ if(Status != NFCSTATUS_SUCCESS)
+ {
+ CRFlag = (uint8_t) PH_FRINFC_MIFARESTD_FLAG1;
+ }
+ }
+
+ if (CRFlag != PH_FRINFC_MIFARESTD_FLAG1)
+ {
+ Status = phFriNfc_MifStd_H_ProWrSectorTrailor(NdefMap);
+ CRFlag = (uint8_t)((Status != NFCSTATUS_PENDING)?
+ PH_FRINFC_MIFARESTD_FLAG1:
+ PH_FRINFC_MIFARESTD_FLAG0);
+ }
+ break;
+
default:
Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
NFCSTATUS_INVALID_DEVICE_REQUEST);
@@ -1532,7 +1584,24 @@ static NFCSTATUS phFriNfc_MifStd_H_AuthSector(phFriNfc_NdefMap_t *NdefMap)
NdefMap->SendRecvBuf[5] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT5; /* 0xA4 */
NdefMap->SendRecvBuf[6] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_MADSECT6; /* 0xA5 */
}
-
+
+ if (NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD ||
+ NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD)
+ {
+ if (NdefMap->StdMifareContainer.ReadOnlySectorIndex &&
+ NdefMap->StdMifareContainer.SectorTrailerBlockNo == NdefMap->StdMifareContainer.currentBlock)
+ {
+ memcpy (&NdefMap->SendRecvBuf[1], &NdefMap->StdMifareContainer.UserScrtKeyB[0], PH_FRINFC_MIFARESTD_KEY_LEN);
+
+ /* Authenticate with KeyB*/
+#ifndef PH_HAL4_ENABLE
+ NdefMap->Cmd.MfCmd = phHal_eMifareCmdListMifareAuthentB;
+#else
+ NdefMap->Cmd.MfCmd = phHal_eMifareAuthentB;
+#endif
+ }
+ }
+
NdefMap->SendLength = MIFARE_AUTHENTICATE_CMD_LENGTH;
*NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
/* Call the Overlapped HAL Transceive function */
@@ -1651,20 +1720,17 @@ static void phFriNfc_MifStd_H_fillAIDarray(phFriNfc_NdefMap_t *NdefMap)
PH_FRINFC_MIFARESTD_NON_NDEF_COMP;
}
}
- else
- {
- /* for Mifare 4k there are 40 sectors, till this number all sectors
- are made NOT NDEF compliant */
- if((NdefMap->StdMifareContainer.aidCompleteFlag == PH_FRINFC_MIFARESTD_FLAG1) &&
+ /* for Mifare 4k there are 40 sectors, till this number all sectors
+ are made NOT NDEF compliant */
+ else if((NdefMap->StdMifareContainer.aidCompleteFlag == PH_FRINFC_MIFARESTD_FLAG1) &&
(NdefMap->CardType == PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD))
+ {
+ for(byteindex = NdefMap->StdMifareContainer.SectorIndex;
+ byteindex < PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR;
+ byteindex++)
{
- for(byteindex = NdefMap->StdMifareContainer.SectorIndex;
- byteindex < PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR;
- byteindex++)
- {
- NdefMap->StdMifareContainer.aid[byteindex] =
- PH_FRINFC_MIFARESTD_NON_NDEF_COMP;
- }
+ NdefMap->StdMifareContainer.aid[byteindex] =
+ PH_FRINFC_MIFARESTD_NON_NDEF_COMP;
}
}
}
@@ -1789,6 +1855,12 @@ static NFCSTATUS phFriNfc_MifStd_H_RdAcsBit(phFriNfc_NdefMap_t *NdefMap)
NFCSTATUS Result = NFCSTATUS_SUCCESS;
NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_ACS_BIT;
+ if( NdefMap->StdMifareContainer.ReadOnlySectorIndex &&
+ NdefMap->StdMifareContainer.currentBlock == NdefMap->StdMifareContainer.SectorTrailerBlockNo)
+ {
+ NdefMap->State = PH_FRINFC_NDEFMAP_STATE_RD_SEC_ACS_BIT;
+ }
+
if(NdefMap->StdMifareContainer.ReadAcsBitFlag == PH_FRINFC_MIFARESTD_FLAG1)
{
/* Get the sector trailer */
@@ -5971,4 +6043,296 @@ static void phFriNfc_MifStd1k_H_BlkChk(phFriNfc_NdefMap_t *NdefMap,
#include <phUnitTestNfc_MifareStd_static.c>
#endif
+/* Convert the Mifare card to ReadOnly.
+ check preconditions before converting to read only
+ 1.shud b rd/write state
+ 2.check NDEF for the card shud b completed
+ 3.if alrady read only return */
+NFCSTATUS
+phFriNfc_MifareStdMap_ConvertToReadOnly (
+ phFriNfc_NdefMap_t *NdefMap,
+ const uint8_t *ScrtKeyB)
+{
+ NFCSTATUS result = NFCSTATUS_SUCCESS;
+ uint8_t totalNoSectors = 0 , sectorTrailerBlockNo = 0;
+
+ if ( NdefMap == NULL)
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else if ( PH_NDEFMAP_CARD_STATE_INVALID == NdefMap->CardState )
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_STATE);
+ }
+ else if (PH_NDEFMAP_CARD_STATE_INITIALIZED == NdefMap->CardState ||
+ PH_NDEFMAP_CARD_STATE_READ_ONLY == NdefMap->CardState )
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NOT_ALLOWED);
+ }
+ else
+ {
+ /* card state is PH_NDEFMAP_CARD_STATE_READ_WRITE now */
+ /* get AID array and parse */
+ if( PH_FRINFC_NDEFMAP_MIFARE_STD_1K_CARD == NdefMap->CardType )
+ {
+ totalNoSectors = PH_FRINFC_MIFARESTD1K_TOTAL_SECTOR;
+ }
+ else if ( PH_FRINFC_NDEFMAP_MIFARE_STD_4K_CARD == NdefMap->CardType )
+ {
+ totalNoSectors = PH_FRINFC_MIFARESTD4K_TOTAL_SECTOR;
+ }
+
+ /* Store Key B in the context */
+ if(ScrtKeyB == NULL)
+ {
+ memset (NdefMap->StdMifareContainer.UserScrtKeyB, PH_FRINFC_MFSTD_FMT_DEFAULT_KEY,
+ PH_FRINFC_MIFARESTD_KEY_LEN);
+ }
+ else
+ {
+ memcpy (NdefMap->StdMifareContainer.UserScrtKeyB, ScrtKeyB, PH_FRINFC_MIFARESTD_KEY_LEN);
+ }
+
+ NdefMap->StdMifareContainer.TotalNoSectors = totalNoSectors;
+ if(totalNoSectors == 0)
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_INVALID_PARAMETER);
+ }
+ else
+ {
+ NdefMap->TLVStruct.NdefTLVFoundFlag = PH_FRINFC_MIFARESTD_FLAG0;
+ NdefMap->StdMifareContainer.RdBeforeWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
+ NdefMap->StdMifareContainer.WrNdefFlag = PH_FRINFC_MIFARESTD_FLAG0;
+ NdefMap->StdMifareContainer.internalLength = PH_FRINFC_MIFARESTD_VAL0;
+ NdefMap->StdMifareContainer.RdAfterWrFlag = PH_FRINFC_MIFARESTD_FLAG0;
+ NdefMap->StdMifareContainer.AuthDone = PH_FRINFC_MIFARESTD_FLAG0;
+ NdefMap->StdMifareContainer.NFCforumSectFlag = PH_FRINFC_MIFARESTD_FLAG0;
+
+ /* Sector 0 is MAD sector .Start from Sector 1 */
+ for(NdefMap->StdMifareContainer.ReadOnlySectorIndex = PH_FRINFC_MIFARESTD_FLAG1;
+ NdefMap->StdMifareContainer.ReadOnlySectorIndex < totalNoSectors;
+ NdefMap->StdMifareContainer.ReadOnlySectorIndex++)
+ {
+ /* skip MAD sectors */
+ if( PH_FRINFC_MIFARESTD_SECTOR_NO16 == NdefMap->StdMifareContainer.ReadOnlySectorIndex )
+ {
+ continue;
+ }
+
+ /* if not NDEF compliant skip */
+ if( PH_FRINFC_MIFARESTD_NON_NDEF_COMP ==
+ NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex])
+ {
+ continue;
+ }
+
+ if (PH_FRINFC_MIFARESTD_NDEF_COMP ==
+ NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex])
+ {
+ /*get the sector trailer block number */
+ sectorTrailerBlockNo =
+ phFriNfc_MifStd_H_GetSectorTrailerBlkNo(NdefMap->StdMifareContainer.ReadOnlySectorIndex);
+ NdefMap->StdMifareContainer.currentBlock = sectorTrailerBlockNo;
+ NdefMap->StdMifareContainer.SectorTrailerBlockNo = sectorTrailerBlockNo;
+
+ /* Proceed to authenticate the sector with Key B
+ and modify the sector trailor bits to make it read only*/
+ result = phFriNfc_MifStd_H_AuthSector(NdefMap);
+
+ if (result == NFCSTATUS_PENDING )
+ {
+ break;
+ }
+ }
+ } /* end for */
+
+ /* There are no NDEF sectors in this card , return */
+ if(NdefMap->StdMifareContainer.ReadOnlySectorIndex == totalNoSectors &&
+ NFCSTATUS_PENDING!= result )
+ {
+ result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NO_NDEF_SUPPORT);
+ }
+ } /* end else */
+ }
+
+ return result;
+}
+
+/* Get the block number of the sector trailor for the given sector trailer Id */
+static uint8_t phFriNfc_MifStd_H_GetSectorTrailerBlkNo(uint8_t SectorID)
+{
+ uint8_t sectorTrailerblockNumber = 0;
+
+ /* every last block of a sector needs to be skipped */
+ if( SectorID < PH_FRINFC_MIFARESTD_SECTOR_NO32 )
+ {
+ sectorTrailerblockNumber = ( SectorID * PH_FRINFC_MIFARESTD_BLK4 ) + 3;
+ }
+ else
+ {
+ sectorTrailerblockNumber = ((PH_FRINFC_MIFARESTD_SECTOR_NO32 * PH_FRINFC_MIFARESTD_BLK4) +
+ ((SectorID - PH_FRINFC_MIFARESTD_SECTOR_NO32) * PH_FRINFC_MIFARESTD_SECTOR_BLOCKS)) + 15;
+ }
+
+ return sectorTrailerblockNumber;
+}
+
+/* Called during ConvertToReadonly process to Authenticate NDEF compliant Sector */
+static NFCSTATUS phFriNfc_MifStd_H_ProSectorTrailorAcsBits(phFriNfc_NdefMap_t *NdefMap)
+{
+ NFCSTATUS Result = NFCSTATUS_SUCCESS;
+
+ if(*NdefMap->SendRecvLength == PH_FRINFC_MIFARESTD_BYTES_READ)
+ {
+ if(NdefMap->StdMifareContainer.ReadAcsBitFlag ==
+ PH_FRINFC_MIFARESTD_FLAG1)
+ {
+ /* check for the correct access bits */
+ Result = phFriNfc_MifStd_H_ChkAcsBit(NdefMap);
+ if(Result == NFCSTATUS_SUCCESS)
+ {
+ if(NdefMap->CardState == PH_NDEFMAP_CARD_STATE_READ_ONLY)
+ {
+ /* No permission to read */
+ Result = PHNFCSTVAL( CID_FRI_NFC_NDEF_MAP, NFCSTATUS_NOT_ALLOWED);
+ }
+ else
+ {
+ /* tranceive to write the data into SendRecvBuff */
+ Result = phFriNfc_MifStd_H_WrSectorTrailorBlock(NdefMap);
+ }
+ }
+ }
+ }
+ else
+ {
+ Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP,
+ NFCSTATUS_INVALID_PARAMETER);
+ }
+
+ return Result;
+}
+
+/* Make current NDEF compliant Sector ReadOnly
+ modify the sector trailor bits and write it to the card*/
+static NFCSTATUS phFriNfc_MifStd_H_WrSectorTrailorBlock(phFriNfc_NdefMap_t *NdefMap)
+{
+ NFCSTATUS status = NFCSTATUS_PENDING;
+
+ /* set the data for additional data exchange*/
+ NdefMap->psDepAdditionalInfo.DepFlags.MetaChaining = 0;
+ NdefMap->psDepAdditionalInfo.DepFlags.NADPresent = 0;
+ NdefMap->psDepAdditionalInfo.NAD = 0;
+ NdefMap->MapCompletionInfo.CompletionRoutine = phFriNfc_MifareStdMap_Process;
+ NdefMap->MapCompletionInfo.Context = NdefMap;
+ NdefMap->PrevOperation = PH_FRINFC_NDEFMAP_WRITE_OPE;
+
+ /* next state (update sector index) */
+ NdefMap->State = PH_FRINFC_NDEFMAP_STATE_WRITE_SEC;
+
+ /* Buffer Check */
+ if(NdefMap->SendRecvBuf != NULL)
+ {
+ NdefMap->SendRecvBuf[10] = 0x00;
+ NdefMap->SendRecvBuf[10] = NdefMap->SendRecvBuf[9] | PH_FRINFC_MIFARESTD_MASK_GPB_WR; /* WR bits 11*/
+
+ /*The NdefMap->SendRecvBuf already has the sector trailor.
+ modify the bits to make Read Only */
+ NdefMap->SendRecvBuf[1] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */
+ NdefMap->SendRecvBuf[2] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */
+ NdefMap->SendRecvBuf[3] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */
+ NdefMap->SendRecvBuf[4] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */
+ NdefMap->SendRecvBuf[5] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT1; /* 0xD3 */
+ NdefMap->SendRecvBuf[6] = PH_FRINFC_NDEFMAP_MIFARESTD_AUTH_NDEFSECT2; /* 0xF7 */
+
+ NdefMap->SendRecvBuf[7] = PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE6;/* 0x07 */
+ NdefMap->SendRecvBuf[8] = PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE7;/* 0x8F */
+ NdefMap->SendRecvBuf[9] = PH_FRINFC_MIFARESTD_NFCSECT_RDACS_BYTE8;/* 0x0F */
+
+ NdefMap->SendRecvBuf[11] = NdefMap->StdMifareContainer.UserScrtKeyB[0];
+ NdefMap->SendRecvBuf[12] = NdefMap->StdMifareContainer.UserScrtKeyB[1];
+ NdefMap->SendRecvBuf[13] = NdefMap->StdMifareContainer.UserScrtKeyB[2];
+ NdefMap->SendRecvBuf[14] = NdefMap->StdMifareContainer.UserScrtKeyB[3];
+ NdefMap->SendRecvBuf[15] = NdefMap->StdMifareContainer.UserScrtKeyB[4];
+ NdefMap->SendRecvBuf[16] = NdefMap->StdMifareContainer.UserScrtKeyB[5];
+
+ /* Write to Ndef Sector Block */
+ NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL0] = NdefMap->StdMifareContainer.currentBlock;
+
+ /* Copy Ndef Sector Block into buffer */
+ (void)memcpy(NdefMap->StdMifareContainer.Buffer,
+ &(NdefMap->SendRecvBuf[PH_FRINFC_MIFARESTD_VAL1]),
+ PH_FRINFC_MIFARESTD_BLOCK_BYTES);
+
+ /* Write from here */
+ NdefMap->SendLength = MIFARE_MAX_SEND_BUF_TO_WRITE;
+#ifndef PH_HAL4_ENABLE
+ NdefMap->Cmd.MfCmd = phHal_eMifareCmdListMifareWrite16;
+#else
+ NdefMap->Cmd.MfCmd = phHal_eMifareWrite16;
+#endif
+ *NdefMap->SendRecvLength = NdefMap->TempReceiveLength;
+
+ /* Call the Overlapped HAL Transceive function */
+ status = phFriNfc_OvrHal_Transceive(NdefMap->LowerDevice,
+ &NdefMap->MapCompletionInfo,
+ NdefMap->psRemoteDevInfo,
+ NdefMap->Cmd,
+ &NdefMap->psDepAdditionalInfo,
+ NdefMap->SendRecvBuf,
+ NdefMap->SendLength,
+ NdefMap->SendRecvBuf,
+ NdefMap->SendRecvLength);
+ }
+ else
+ {
+ /* Error: The control should not ideally come here.
+ Return Error.*/
+#ifndef PH_HAL4_ENABLE
+ status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_CMD_ABORTED);
+#else
+ status = PHNFCSTVAL(CID_FRI_NFC_NDEF_MAP, NFCSTATUS_FAILED);
+#endif
+ }
+
+ return status;
+}
+
+/* Make next NDEF compliant Sector ReadOnly */
+static NFCSTATUS phFriNfc_MifStd_H_ProWrSectorTrailor(phFriNfc_NdefMap_t *NdefMap)
+{
+ NFCSTATUS status = NFCSTATUS_FAILED;
+ uint8_t sectorTrailerBlockNo = 0;
+
+ /*Increment Sector Index */
+ NdefMap->StdMifareContainer.ReadOnlySectorIndex++;
+
+ /* skip if MAD2 */
+ if(PH_FRINFC_MIFARESTD_SECTOR_NO16 == NdefMap->StdMifareContainer.ReadOnlySectorIndex )
+ {
+ NdefMap->StdMifareContainer.ReadOnlySectorIndex++;
+ }
+
+ /* if current sector index exceeds total sector index then
+ all ndef sectors are made readonly then return success
+ If a NON def sector is encountered return success*/
+ if (NdefMap->StdMifareContainer.ReadOnlySectorIndex >= NdefMap->StdMifareContainer.TotalNoSectors ||
+ PH_FRINFC_MIFARESTD_NON_NDEF_COMP ==
+ NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex])
+ {
+ status = NFCSTATUS_SUCCESS;
+ }
+ else if(PH_FRINFC_MIFARESTD_NDEF_COMP == NdefMap->StdMifareContainer.aid[NdefMap->StdMifareContainer.ReadOnlySectorIndex])
+ {
+ /* Convert next NDEF sector to read only */
+ sectorTrailerBlockNo = phFriNfc_MifStd_H_GetSectorTrailerBlkNo(NdefMap->StdMifareContainer.ReadOnlySectorIndex);
+ NdefMap->StdMifareContainer.currentBlock = sectorTrailerBlockNo;
+ NdefMap->StdMifareContainer.SectorTrailerBlockNo = sectorTrailerBlockNo;
+
+ status = phFriNfc_MifStd_H_AuthSector(NdefMap);
+ }
+
+ return status;
+}
+
#endif /* PH_FRINFC_MAP_MIFARESTD_DISABLED */
diff --git a/src/phFriNfc_MifareStdMap.h b/src/phFriNfc_MifareStdMap.h
index 44cd895..aeea7e7 100644
--- a/src/phFriNfc_MifareStdMap.h
+++ b/src/phFriNfc_MifareStdMap.h
@@ -88,6 +88,8 @@
#define PH_FRINFC_NDEFMAP_STATE_DISCONNECT 14 /*!< Disconnect in progress */
#define PH_FRINFC_NDEFMAP_STATE_CONNECT 15 /*!< Connect in progress */
+#define PH_FRINFC_NDEFMAP_STATE_RD_SEC_ACS_BIT 16 /*!< Convert to ReadOnly in progress */
+#define PH_FRINFC_NDEFMAP_STATE_WRITE_SEC 17 /*!< Convert to ReadOnly in progress */
/*@}*/
@@ -188,6 +190,7 @@
#define PH_FRINFC_MIFARESTD1K_TOTAL_SECTOR 16 /*!< Sector 40 */
#define PH_FRINFC_MIFARESTD_BYTES_READ 16 /*!< Bytes read */
#define PH_FRINFC_MIFARESTD_BLOCK_BYTES 16 /*!< Bytes per block */
+#define PH_FRINFC_MIFARESTD_SECTOR_BLOCKS 16 /*!< Blocks per sector */
#define PH_FRINFC_MIFARESTD_WR_A_BLK 17 /*!< 17 bytes (including current block)
are given to transfer */
#define PH_FRINFC_MIFARESTD4K_MAX_BLOCKS 210 /*!< Maximum number of Mifare 4k Blocks
@@ -235,6 +238,7 @@
#define PH_FRINFC_MIFARESTD_MASK_GPB_WR 0x03 /*!< Mask 0x03 for GPB byte */
#define PH_FRINFC_MIFARESTD_MASK_GPB_RD 0x0C /*!< Mask 0xOC for GPB byte */
#define PH_FRINFC_MIFARESTD_GPB_RD_WR_VAL 0x00 /*!< GPB Read Write value */
+#define PH_FRINFC_MIFARESTD_KEY_LEN 0x06 /*!< MIFARE Std key length */
/*@}*/
@@ -374,5 +378,20 @@ NFCSTATUS phFriNfc_MifareStdMap_ChkNdef(phFriNfc_NdefMap_t *NdefMap);
void phFriNfc_MifareStdMap_Process( void *Context,
NFCSTATUS Status);
-#endif /* PHFRINFC_MIFARESTDMAP_H */
+/*!
+ *
+ * The function Convert the Mifare card to ReadOnly.
+ *
+ * \param[in] NdefMap Pointer to a valid instance of the \ref phFriNfc_NdefMap_t structure describing
+ * the component context.
+ *
+ * \retval NFCSTATUS_PENDING The action has been successfully triggered.
+ * \retval NFCSTATUS_INVALID_PARAMETER At least one parameter of the function is invalid.
+ * \retval NFCSTATUS_INVALID_STATE The mifare card should be in read_write state to convert card to
+ * readonly.If any other state the function return NFCSTATUS_INVALID_STATE
+ *\retval NFCSTATUS_NOT_ALLOWED If card is already in read_only state or initialized state
+ *
+ */
+NFCSTATUS phFriNfc_MifareStdMap_ConvertToReadOnly(phFriNfc_NdefMap_t *NdefMap, const uint8_t *ScrtKeyB);
+#endif /* PHFRINFC_MIFARESTDMAP_H */
diff --git a/src/phFriNfc_NdefMap.h b/src/phFriNfc_NdefMap.h
index 13eb348..b559d4d 100644
--- a/src/phFriNfc_NdefMap.h
+++ b/src/phFriNfc_NdefMap.h
@@ -488,6 +488,15 @@ typedef struct phFriNfc_MifareStdCont
/** Flag is to know that this is first time the write has been called. This
is required when the card formatted with the 3rd configuration */
uint8_t FirstWriteFlag;
+ /** Indicates the sector trailor id for which the convert
+ to read only is currently in progress*/
+ uint8_t ReadOnlySectorIndex;
+ /** Indicates the total number of sectors on the card */
+ uint8_t TotalNoSectors;
+ /** Indicates the block number of the sector trailor on the card */
+ uint8_t SectorTrailerBlockNo;
+ /** Secret key B to given by the application */
+ uint8_t UserScrtKeyB[6];
}phFriNfc_MifareStdCont_t;
/*@}*/
#endif /* PH_FRINFC_MAP_MIFARESTD_DISABLED */
diff --git a/src/phLibNfc.h b/src/phLibNfc.h
index e4e41cf..1eb62ae 100644
--- a/src/phLibNfc.h
+++ b/src/phLibNfc.h
@@ -1991,6 +1991,8 @@ NFCSTATUS phLibNfc_RemoteDev_FormatNdef(phLibNfc_Handle hRemoteDevice,
*\param[in] hRemoteDevice handle of the remote device.This handle to be
* same as as handle obtained for specific remote device
* during device discovery.
+*\param[in] pScrtKey Key to be used for making Mifare read only. This parameter is
+* unused in case of readonly for other cards.
*\param[in] pNdefReadOnly_RspCb Response callback defined by the caller.
*\param[in] pContext Client context which will be included in
* callback when the request is completed.
@@ -2037,9 +2039,10 @@ NFCSTATUS phLibNfc_RemoteDev_FormatNdef(phLibNfc_Handle hRemoteDevice,
* \param NFCSTATUS_FAILED Request failed.
*/
-NFCSTATUS phLibNfc_ConvertToReadOnlyNdef (phLibNfc_Handle hRemoteDevice,
- pphLibNfc_RspCb_t pNdefReadOnly_RspCb,
- void* pContext
+NFCSTATUS phLibNfc_ConvertToReadOnlyNdef (phLibNfc_Handle hRemoteDevice,
+ phNfc_sData_t* pScrtKey,
+ pphLibNfc_RspCb_t pNdefReadOnly_RspCb,
+ void* pContext
);
#endif /* #ifdef LIBNFC_READONLY_NDEF */
diff --git a/src/phLibNfc_ndef_raw.c b/src/phLibNfc_ndef_raw.c
index d3c3e6a..15ad001 100644
--- a/src/phLibNfc_ndef_raw.c
+++ b/src/phLibNfc_ndef_raw.c
@@ -39,6 +39,7 @@
#include <phLibNfc_initiator.h>
#include <phLibNfc_discovery.h>
#include <phFriNfc_NdefReg.h>
+#include <phFriNfc_MifareStdMap.h>
/*
*************************** Macro's ****************************************
@@ -122,6 +123,7 @@ NFCSTATUS phLibNfc_Ndef_Read( phLibNfc_Handle hRemoteDevice,
)
{
NFCSTATUS RetVal = NFCSTATUS_FAILED;
+
if((NULL == gpphLibContext)||
(gpphLibContext->LibNfcState.cur_state == eLibNfcHalStateShutdown))
{
@@ -1345,11 +1347,14 @@ NFCSTATUS phLibNfc_RemoteDev_FormatNdef(phLibNfc_Handle hRemoteDevice,
NFCSTATUS
phLibNfc_ConvertToReadOnlyNdef (
phLibNfc_Handle hRemoteDevice,
+ phNfc_sData_t* pScrtKey,
pphLibNfc_RspCb_t pNdefReadOnly_RspCb,
void* pContext
)
{
NFCSTATUS ret_val = NFCSTATUS_FAILED;
+ static uint8_t mif_std_key[6] ={0},
+ Index = 0;
if ((NULL == gpphLibContext)
|| (gpphLibContext->LibNfcState.cur_state
@@ -1406,14 +1411,34 @@ phLibNfc_ConvertToReadOnlyNdef (
case phHal_eMifare_PICC:
case phHal_eISO14443_A_PICC:
{
- if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType)
+ if ((phHal_eMifare_PICC == ps_rem_dev_info->RemDevType)
&& (0x00 != ps_rem_dev_info->RemoteDevInfo.Iso14443A_Info.Sak))
{
- /* Mifare classic 1k/4k not supported */
- ret_val = NFCSTATUS_REJECTED;
+ for (fun_id = 0; fun_id < PH_FRINFC_NDEFMAP_CR; fun_id++)
+ {
+ /* Register the callback for the check ndef */
+ ret_val = phFriNfc_NdefMap_SetCompletionRoutine (
+ gpphLibContext->ndef_cntx.psNdefMap,
+ fun_id, phLibNfc_Ndef_ReadOnly_Cb,
+ (void *)gpphLibContext);
+ }
+
+ /* Start mifare NFC read only function */
+ /* mif_std_key is required to format the mifare 1k/4k card */
+ if(pScrtKey != NULL && pScrtKey->length == MIFARE_STD_KEY_LEN)
+ {
+ for (Index =0 ;Index < (pScrtKey->length); Index++ )
+ {
+ mif_std_key[Index] = *(pScrtKey->buffer++);
+ }
+
+ ret_val = phFriNfc_MifareStdMap_ConvertToReadOnly (
+ gpphLibContext->ndef_cntx.psNdefMap, mif_std_key);
+ ret_val = PHNFCSTATUS(ret_val);
+ }
}
else
- {
+ {
gpphLibContext->ndef_cntx.NdefSendRecvLen = NDEF_SENDRCV_BUF_LEN;
/* Call ndef format reset, this will initialize the ndef
diff --git a/src/phLibNfc_ndef_raw.h b/src/phLibNfc_ndef_raw.h
index ffeff2c..036803c 100644
--- a/src/phLibNfc_ndef_raw.h
+++ b/src/phLibNfc_ndef_raw.h
@@ -59,6 +59,7 @@ typedef enum phLibNfc_Last_Call{
#define NDEF_MIFARE_4K_LEN 3356U
#define NDEF_MIFARE_1K_LEN 716U
#define MIFARE_STD_DEFAULT_KEY {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}
+#define MIFARE_STD_KEY_LEN 6
#define ISO_SAK_VALUE 0x20U