From 40734e7599249717860f7aeabda494e1bcd86ffe Mon Sep 17 00:00:00 2001 From: Sunil Jogi Date: Thu, 12 Jan 2012 13:47:03 -0800 Subject: Mifare readonly support. This patch requires changes done in following projects submited as patches: 1. packages/apps/Nfc 2. frameworks/base Change-Id: I9036309d82dd897e77f6bc14c30fbde255bf955c --- src/phFriNfc_MapTools.c | 12 ++ src/phFriNfc_MifareStdMap.c | 392 ++++++++++++++++++++++++++++++++++++++++++-- src/phFriNfc_MifareStdMap.h | 21 ++- src/phFriNfc_NdefMap.h | 9 + src/phLibNfc.h | 9 +- src/phLibNfc_ndef_raw.c | 33 +++- src/phLibNfc_ndef_raw.h | 1 + 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 +#include + /*! \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 #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 #include #include +#include /* *************************** 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 -- cgit v1.1