static NFCSTATUS phFriNfc_TopazDynamicFormat_ProcessWritingTermTlvBytes(phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt) { static const uint8_t c_expectedResponse[] = { PH_FRINFC_TOPAZ_TLV_TERM_T, /* Terminator TLV */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Rest of data bytes are zeros */ }; NFCSTATUS wStatus = NFCSTATUS_SUCCESS; PH_LOG_NDEF_FUNC_ENTRY(); assert(NdefSmtCrdFmt != NULL); if ((*NdefSmtCrdFmt->SendRecvLength != sizeof(c_expectedResponse)) || (0 != phOsalNfc_MemCompare(NdefSmtCrdFmt->SendRecvBuf, (void*)c_expectedResponse, sizeof(c_expectedResponse)))) { PH_LOG_NDEF_WARN_STR("Unexpected response received. Formatting failed"); wStatus = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); } else { PH_LOG_NDEF_INFO_STR("Successfully formatted dynamic Topaz card"); } PH_LOG_NDEF_FUNC_EXIT(); return wStatus; }
NFCSTATUS phFriNfc_TopazFormat_Format(phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt) { NFCSTATUS wStatus = NFCSTATUS_SUCCESS; PH_LOG_NDEF_FUNC_ENTRY(); if (NdefSmtCrdFmt == NULL) { wStatus = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER); } else { NdefSmtCrdFmt->State = 0; phOsalNfc_SetMemory(&NdefSmtCrdFmt->AddInfo.Type1Info, 0, sizeof(NdefSmtCrdFmt->AddInfo.Type1Info)); NdefSmtCrdFmt->AddInfo.Type1Info.CurrentBlock = 0x01; NdefSmtCrdFmt->AddInfo.Type1Info.CurrentByte = 0; wStatus = phFriNfc_TopazFormat_WriteByte(NdefSmtCrdFmt, NdefSmtCrdFmt->AddInfo.Type1Info.CurrentBlock, NdefSmtCrdFmt->AddInfo.Type1Info.CurrentByte, c_staticTopazFormat[NdefSmtCrdFmt->AddInfo.Type1Info.CurrentByte]); } PH_LOG_NDEF_FUNC_EXIT(); return wStatus; }
static NFCSTATUS phFriNfc_TopazFormat_WriteByte(phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt, uint8_t BlockNo, uint8_t ByteNo, uint8_t ByteToWrite) { NFCSTATUS wStatus = NFCSTATUS_SUCCESS; uint8_t writeCmd[7] = { 0 }; PH_LOG_NDEF_FUNC_ENTRY(); assert(NdefSmtCrdFmt != NULL); writeCmd[0] = PH_FRINFC_TOPAZ_CMD_WRITE_1E; /* Block and byte numbers need to be in the following format: 7 | 6 5 4 3 | 2 1 0 | 0 | Block | Byte | */ writeCmd[1] = ((BlockNo & 0x0F) << 3) | (ByteNo & 0x07); writeCmd[2] = ByteToWrite; /* Copy the UID to the end of command buffer */ phOsalNfc_MemCopy(&writeCmd[3], NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid, TOPAZ_UID_LENGTH); wStatus = phFriNfc_TopazFormat_Transceive(NdefSmtCrdFmt, writeCmd, sizeof(writeCmd)); PH_LOG_NDEF_FUNC_EXIT(); return wStatus; }
static NFCSTATUS phFriNfc_MfUL_H_Transceive(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS Result = NFCSTATUS_SUCCESS; PH_LOG_NDEF_FUNC_ENTRY(); /* set the data for additional data exchange*/ NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0; NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0; NdefSmtCrdFmt->psDepAdditionalInfo.NodeAddress = 0; /*set the completion routines for the card operations*/ NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process; NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt; *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE; /* Call the Overlapped HAL Transceive function */ Result = phFriNfc_OvrHal_Transceive( NdefSmtCrdFmt->LowerDevice, &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo, NdefSmtCrdFmt->psRemoteDevInfo, NdefSmtCrdFmt->Cmd, &NdefSmtCrdFmt->psDepAdditionalInfo, NdefSmtCrdFmt->SendRecvBuf, NdefSmtCrdFmt->SendLength, NdefSmtCrdFmt->SendRecvBuf, NdefSmtCrdFmt->SendRecvLength); PH_LOG_NDEF_FUNC_EXIT(); return Result; }
NFCSTATUS phFriNfc_MfUL_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS Result = NFCSTATUS_SUCCESS; uint8_t OTPBytes[] = PH_FRINFC_MFUL_FMT_OTP_BYTES_TEMPLATE; PH_LOG_NDEF_FUNC_ENTRY(); if (NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.ULType == phNfc_eMifareULType_UltralightC) { NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD; OTPBytes[PH_FRINFC_MFUL_FMT_OTP_DATA_AREA_SIZE_BYTE] = PH_FRINFC_MFULC_FMT_DATA_AREA_SIZE; phOsalNfc_MemCopy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, OTPBytes, sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); } else if (NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.ULType == phNfc_eMifareULType_UltralightEV1) { /* The NDEF TLV for Ultralight and Ultralight EV1 cards are the same, so just label the CardType as Ultralight */ NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD; OTPBytes[PH_FRINFC_MFUL_FMT_OTP_DATA_AREA_SIZE_BYTE] = NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Iso14443A_Info.DataAreaSize >> 3; // Divide by 8 phOsalNfc_MemCopy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, OTPBytes, sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); }
static NFCSTATUS phFriNfc_MfUL_H_WrRd( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) { NFCSTATUS Result = NFCSTATUS_SUCCESS; PH_LOG_NDEF_FUNC_ENTRY(); /* Fill the send buffer */ phFriNfc_MfUL_H_fillSendBuf(NdefSmtCrdFmt, NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock); /* Call transceive */ Result = phFriNfc_MfUL_H_Transceive (NdefSmtCrdFmt); PH_LOG_NDEF_FUNC_EXIT(); return Result; }
void phFriNfc_MfUL_Reset(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { uint8_t OTPByte[] = PH_FRINFC_MFUL_FMT_OTP_BYTES; PH_LOG_NDEF_FUNC_ENTRY(); NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_0; phOsalNfc_MemCopy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, OTPByte, sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[0] = 0; NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[1] = 0; NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[2] = 0; NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[3] = 0; PH_LOG_NDEF_FUNC_EXIT(); }
static NFCSTATUS phFriNfc_TopazDynamicFormat_ProcessWritingMemCtrlBytes(phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt) { static const uint8_t c_expectedResponse[] = { PH_FRINFC_TOPAZ_TLV_LOCK_CTRL_V2, /* Lock control bytes */ PH_FRINFC_TOPAZ_TLV_MEM_CTRL_T, PH_FRINFC_TOPAZ_TLV_MEM_CTRL_L, PH_FRINFC_TOPAZ_TLV_MEM_CTRL_V0, PH_FRINFC_TOPAZ_TLV_MEM_CTRL_V1, PH_FRINFC_TOPAZ_TLV_MEM_CTRL_V2, /* Memory control bytes */ PH_FRINFC_TOPAZ_TLV_NDEF_T, PH_FRINFC_TOPAZ_TLV_NDEF_L, /* NDEF TLV */ }; uint8_t write8Cmd[] = { PH_FRINFC_TOPAZ_CMD_WRITE_E8, /* WRITE-E8 */ 0x03, /* Block 0x3 */ PH_FRINFC_TOPAZ_TLV_TERM_T, /* Terminator TLV */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* Rest of data bytes are zeros */ 0x00, 0x00, 0x00, 0x00 /* UID bytes (need to be copied over) */ }; NFCSTATUS wStatus = NFCSTATUS_SUCCESS; PH_LOG_NDEF_FUNC_ENTRY(); assert(NdefSmtCrdFmt != NULL); if ((*NdefSmtCrdFmt->SendRecvLength != sizeof(c_expectedResponse)) || (0 != phOsalNfc_MemCompare(NdefSmtCrdFmt->SendRecvBuf, (void*)c_expectedResponse, sizeof(c_expectedResponse)))) { PH_LOG_NDEF_WARN_STR("Unexpected response received. Formatting failed"); wStatus = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); } else { /* Copy the UID to the end of command buffer */ phOsalNfc_MemCopy(&write8Cmd[10], NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid, TOPAZ_UID_LENGTH); NdefSmtCrdFmt->State = PH_FRINFC_TOPAZ_STATE_WRITE_TERM_TLV_BYTES; wStatus = phFriNfc_TopazFormat_Transceive(NdefSmtCrdFmt, write8Cmd, sizeof(write8Cmd)); } PH_LOG_NDEF_FUNC_EXIT(); return wStatus; }
NFCSTATUS phFriNfc_MfUL_ConvertToReadOnly ( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS result = NFCSTATUS_SUCCESS; PH_LOG_NDEF_FUNC_ENTRY(); NdefSmtCrdFmt->AddInfo.Type2Info.DefaultLockBytesFlag = TRUE; NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex = 0; NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_RD_16BYTES; result = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); PH_LOG_NDEF_FUNC_EXIT(); return result; }
static NFCSTATUS phFriNfc_MfUL_H_ProWrOTPBytes( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) { NFCSTATUS Result = NFCSTATUS_SUCCESS; PH_LOG_NDEF_FUNC_ENTRY(); /* Card already have the OTP bytes so write TLV */ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV; /* Write NDEF TLV in block number 4 */ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_4; Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt); PH_LOG_NDEF_FUNC_EXIT(); return Result; }
static int MemCompare1 ( void *s1, void *s2, unsigned int n ) { int8_t diff = 0; int8_t *char_1 =(int8_t *)s1; int8_t *char_2 =(int8_t *)s2; PH_LOG_NDEF_FUNC_ENTRY(); if(NULL == s1 || NULL == s2) { } else { for(;((n>0)&&(diff==0));n--,char_1++,char_2++) { diff = *char_1 - *char_2; } } PH_LOG_NDEF_FUNC_EXIT(); return (int)diff; }
void phFriNfc_TopazFormat_Process(void* Context, NFCSTATUS Status) { NFCSTATUS wStatus = Status; phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t*)Context; PH_LOG_NDEF_FUNC_ENTRY(); if (NdefSmtCrdFmt == NULL) { wStatus = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER); } else if (wStatus == NFCSTATUS_SUCCESS) { if (*NdefSmtCrdFmt->SendRecvLength != 1 || NdefSmtCrdFmt->SendRecvBuf[0] != c_staticTopazFormat[NdefSmtCrdFmt->AddInfo.Type1Info.CurrentByte]) { PH_LOG_NDEF_WARN_STR("Unexpected response received. Formatting failed"); wStatus = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); } else { NdefSmtCrdFmt->AddInfo.Type1Info.CurrentByte++; if (NdefSmtCrdFmt->AddInfo.Type1Info.CurrentByte < ARRAYSIZE(c_staticTopazFormat)) { wStatus = phFriNfc_TopazFormat_WriteByte(NdefSmtCrdFmt, NdefSmtCrdFmt->AddInfo.Type1Info.CurrentBlock, NdefSmtCrdFmt->AddInfo.Type1Info.CurrentByte, c_staticTopazFormat[NdefSmtCrdFmt->AddInfo.Type1Info.CurrentByte]); } } } /* If status is not pending (i.e. we are waiting for a response from the card), then call the completion routine */ if (wStatus != NFCSTATUS_PENDING) { phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, wStatus); } PH_LOG_NDEF_FUNC_EXIT(); }
static NFCSTATUS phFriNfc_TopazFormat_Transceive(phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt, const uint8_t* SendBuffer, uint16_t SendBufferLength) { NFCSTATUS wStatus = NFCSTATUS_SUCCESS; PH_LOG_NDEF_FUNC_ENTRY(); assert(NdefSmtCrdFmt != NULL); assert(SendBuffer != NULL); assert(SendBufferLength != 0 && SendBufferLength <= PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE); /* Fill the send buffer */ NdefSmtCrdFmt->Cmd.JewelCmd = phNfc_eJewel_Raw; phOsalNfc_MemCopy(NdefSmtCrdFmt->SendRecvBuf, SendBuffer, SendBufferLength); NdefSmtCrdFmt->SendLength = SendBufferLength; /* Set the data for additional data exchange */ NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.MetaChaining = 0; NdefSmtCrdFmt->psDepAdditionalInfo.DepFlags.NADPresent = 0; NdefSmtCrdFmt->psDepAdditionalInfo.NodeAddress = 0; /* Set the completion routines for the card operations */ NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.CompletionRoutine = phFriNfc_NdefSmtCrd_Process; NdefSmtCrdFmt->SmtCrdFmtCompletionInfo.Context = NdefSmtCrdFmt; *NdefSmtCrdFmt->SendRecvLength = PH_FRINFC_SMTCRDFMT_MAX_SEND_RECV_BUF_SIZE; wStatus = phFriNfc_OvrHal_Transceive(NdefSmtCrdFmt->LowerDevice, &NdefSmtCrdFmt->SmtCrdFmtCompletionInfo, NdefSmtCrdFmt->psRemoteDevInfo, NdefSmtCrdFmt->Cmd, &NdefSmtCrdFmt->psDepAdditionalInfo, NdefSmtCrdFmt->SendRecvBuf, NdefSmtCrdFmt->SendLength, NdefSmtCrdFmt->SendRecvBuf, NdefSmtCrdFmt->SendRecvLength); PH_LOG_NDEF_FUNC_EXIT(); return wStatus; }
NFCSTATUS phFriNfc_MfUL_Format(phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt) { NFCSTATUS Result = NFCSTATUS_SUCCESS; uint8_t OTPByte[] = PH_FRINFC_MFUL_FMT_OTP_BYTES; PH_LOG_NDEF_FUNC_ENTRY(); NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_0; phOsalNfc_MemCopy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, OTPByte, sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); /* Set the state */ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RD_16BYTES; /* Initialise current block to the lock bits block */ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_2; /* Start authentication */ Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt); PH_LOG_NDEF_FUNC_EXIT(); return Result; }
void phFriNfc_TopazDynamicFormat_Process(void* Context, NFCSTATUS Status) { NFCSTATUS wStatus = Status; phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t*)Context; PH_LOG_NDEF_FUNC_ENTRY(); if (NdefSmtCrdFmt == NULL) { wStatus = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER); } else if (wStatus == NFCSTATUS_SUCCESS) { switch (NdefSmtCrdFmt->State) { case PH_FRINFC_TOPAZ_STATE_WRITE_CC_BYTES: wStatus = phFriNfc_TopazDynamicFormat_ProcessWritingCCBytes(NdefSmtCrdFmt); break; case PH_FRINFC_TOPAZ_STATE_WRITE_MEM_CTRL_BYTES: wStatus = phFriNfc_TopazDynamicFormat_ProcessWritingMemCtrlBytes(NdefSmtCrdFmt); break; case PH_FRINFC_TOPAZ_STATE_WRITE_TERM_TLV_BYTES: wStatus = phFriNfc_TopazDynamicFormat_ProcessWritingTermTlvBytes(NdefSmtCrdFmt); break; default: wStatus = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_DEVICE_REQUEST); break; } } /* If status is not pending (i.e. we are waiting for a response from the card), then call the completion routine */ if (wStatus != NFCSTATUS_PENDING) { phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, wStatus); } PH_LOG_NDEF_FUNC_EXIT(); }
NFCSTATUS phFriNfc_TopazDynamicFormat_Format(phFriNfc_sNdefSmtCrdFmt_t* NdefSmtCrdFmt) { uint8_t write8Cmd[] = { PH_FRINFC_TOPAZ_CMD_WRITE_E8, /* WRITE-E8 */ 0x01, /* Block 0x1 */ PH_FRINFC_TOPAZ_CC_BYTE0, PH_FRINFC_TOPAZ_CC_BYTE1, PH_FRINFC_TOPAZ_DYNAMIC_CC_BYTE2_MMSIZE, PH_FRINFC_TOPAZ_CC_BYTE3_RW, /* CC bytes */ PH_FRINFC_TOPAZ_TLV_LOCK_CTRL_T, PH_FRINFC_TOPAZ_TLV_LOCK_CTRL_L, PH_FRINFC_TOPAZ_TLV_LOCK_CTRL_V0, PH_FRINFC_TOPAZ_TLV_LOCK_CTRL_V1, /* Lock control bytes */ 0x00, 0x00, 0x00, 0x00 /* UID bytes (need to be copied over) */ }; NFCSTATUS wStatus = NFCSTATUS_SUCCESS; PH_LOG_NDEF_FUNC_ENTRY(); if (NdefSmtCrdFmt == NULL) { wStatus = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_PARAMETER); } else { /* Copy the UID to the end of command buffer */ phOsalNfc_MemCopy(&write8Cmd[10], NdefSmtCrdFmt->psRemoteDevInfo->RemoteDevInfo.Jewel_Info.Uid, TOPAZ_UID_LENGTH); NdefSmtCrdFmt->State = PH_FRINFC_TOPAZ_STATE_WRITE_CC_BYTES; wStatus = phFriNfc_TopazFormat_Transceive(NdefSmtCrdFmt, write8Cmd, sizeof(write8Cmd)); } PH_LOG_NDEF_FUNC_EXIT(); return wStatus; }
void phFriNfc_MfUL_Process(void *Context, NFCSTATUS Status) { phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt = (phFriNfc_sNdefSmtCrdFmt_t *)Context; PH_LOG_NDEF_FUNC_ENTRY(); if(Status == NFCSTATUS_SUCCESS) { switch(NdefSmtCrdFmt->State) { case PH_FRINFC_MFUL_FMT_RD_16BYTES: Status = phFriNfc_MfUL_H_ProRd16Bytes(NdefSmtCrdFmt); break; case PH_FRINFC_MFUL_FMT_WR_OTPBYTES: Status = phFriNfc_MfUL_H_ProWrOTPBytes(NdefSmtCrdFmt); break; case PH_FRINFC_MFUL_FMT_WR_TLV: if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD) { /* Write NDEF TLV in block number 5 */ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_5; /* Card already have the OTP bytes so write TLV */ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV1; Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); } break; case PH_FRINFC_MFUL_FMT_RO_RD_16BYTES: { if (MIFARE_UL_READ_MAX_SIZE == *NdefSmtCrdFmt->SendRecvLength) { uint8_t otp_lock_page_size = 0; uint8_t i = 0; otp_lock_page_size = sizeof (NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes); (void)phOsalNfc_MemCopy ((void *)NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes, (void *)NdefSmtCrdFmt->SendRecvBuf, sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes)); NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[2] = (uint8_t) (NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[2] | MIFARE_UL_LOCK_BYTE1_VALUE); NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes[3] = MIFARE_UL_LOCK_BYTE2_VALUE; i = (uint8_t)(i + otp_lock_page_size); otp_lock_page_size = sizeof (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes); phOsalNfc_MemCopy ((void *)NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, (void *)(NdefSmtCrdFmt->SendRecvBuf + i), sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[(otp_lock_page_size - 1)] = READ_ONLY_VALUE_IN_OTP; switch (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[TYPE_2_MEM_SIZE_POSITION]) { case TYPE_2_STATIC_MEM_SIZE_VALUE: { NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES; Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); break; } case TYPE_2_DYNAMIC_MEM_SIZE_VALUE: { NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES; /* Start reading from block 4 */ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = 4; Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); break; } default: { Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_DEVICE_REQUEST); break; } } } else { Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_RECEIVE_LENGTH); } break; } case PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES: { switch (NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes[TYPE_2_MEM_SIZE_POSITION]) { case TYPE_2_STATIC_MEM_SIZE_VALUE: case TYPE_2_DYNAMIC_MEM_SIZE_VALUE: { NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_LOCK_BYTES; Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); break; } default: { Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_DEVICE_REQUEST); break; } } break; } case PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES: { if (MIFARE_UL_READ_MAX_SIZE == *NdefSmtCrdFmt->SendRecvLength) { Status = phFriNfc_MfUL_ParseTLVs (NdefSmtCrdFmt, NdefSmtCrdFmt->SendRecvBuf, (uint8_t)*NdefSmtCrdFmt->SendRecvLength); if (!Status) { NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = NdefSmtCrdFmt->AddInfo.Type2Info.LockBlockNumber; Status = phFriNfc_MfUL_ReadWriteLockBytes (NdefSmtCrdFmt); } } else { Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_RECEIVE_LENGTH); } break; } case PH_FRINFC_MFUL_FMT_RO_RD_DYN_LOCK_BYTES: { if (MIFARE_UL_READ_MAX_SIZE == *NdefSmtCrdFmt->SendRecvLength) { (void)phOsalNfc_MemCopy ((void *)NdefSmtCrdFmt->AddInfo.Type2Info.ReadData, (void *)NdefSmtCrdFmt->SendRecvBuf, sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.ReadData)); NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex = 0; Status = phFriNfc_MfUL_UpdateAndWriteLockBits (NdefSmtCrdFmt); } else { Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_RECEIVE_LENGTH); } break; } case PH_FRINFC_MFUL_FMT_RO_WR_DYN_LOCK_BYTES: { NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex = (uint8_t) (NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex + MFUL_BLOCK_SIZE_IN_BYTES); if (!phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt)) { /* There is no lock bits to write, then write OTP bytes */ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES; Status = phFriNfc_MfUL_H_WrRd (NdefSmtCrdFmt); } else if ((NdefSmtCrdFmt->AddInfo.Type2Info.ReadDataIndex < MIFARE_UL_READ_MAX_SIZE) && (phFriNfc_MfUL_CalcRemainingLockBits (NdefSmtCrdFmt))) { /* If remaining lock bits has to be written and the data is already read */ Status = phFriNfc_MfUL_UpdateAndWriteLockBits (NdefSmtCrdFmt); } else { /* Increment current block by 4 because if a data is read then 16 bytes will be given which is 4 blocks */ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = (uint8_t) (NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock + 4); Status = phFriNfc_MfUL_ReadWriteLockBytes (NdefSmtCrdFmt); } break; } case PH_FRINFC_MFUL_FMT_RO_WR_LOCK_BYTES: { /* Do nothing */ break; } case PH_FRINFC_MFUL_FMT_WR_TLV1: break; default: Status = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_INVALID_DEVICE_REQUEST); break; } } /* Status is not success then call completion routine */ if(Status != NFCSTATUS_PENDING) { phFriNfc_SmtCrdFmt_HCrHandler(NdefSmtCrdFmt, Status); } PH_LOG_NDEF_FUNC_EXIT(); }
static NFCSTATUS phFriNfc_MfUL_H_ProRd16Bytes( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt ) { NFCSTATUS Result = PHNFCSTVAL(CID_FRI_NFC_NDEF_SMTCRDFMT, NFCSTATUS_FORMAT_ERROR); uint32_t memcompare = PH_FRINFC_MFUL_FMT_VAL_0; uint8_t ZeroBuf[] = {0x00, 0x00, 0x00, 0x00}; uint8_t OTPByteUL[] = PH_FRINFC_MFUL_FMT_OTP_BYTES; uint8_t OTPByteULC[] = PH_FRINFC_MFULC_FMT_OTP_BYTES; PH_LOG_NDEF_FUNC_ENTRY(); /* Check the lock bits (byte number 2 and 3 of block number 2) */ if ((NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_2] == PH_FRINFC_MFUL_FMT_LOCK_BITS_VAL) && (NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_3] == PH_FRINFC_MFUL_FMT_LOCK_BITS_VAL)) { if (NdefSmtCrdFmt->SendRecvBuf[8] == 0x02 && NdefSmtCrdFmt->SendRecvBuf[9] == 0x00) { NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD; phOsalNfc_MemCopy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, OTPByteULC, sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); } else if (NdefSmtCrdFmt->SendRecvBuf[8] == 0xFF && NdefSmtCrdFmt->SendRecvBuf[9] == 0xFF) { NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD; phOsalNfc_MemCopy(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, OTPByteUL, sizeof(NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes)); } else { NdefSmtCrdFmt->CardType = PH_FRINFC_NDEFMAP_MIFARE_UL_CARD; } memcompare = (uint32_t) MemCompare1(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_4], NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, PH_FRINFC_MFUL_FMT_VAL_4); if (memcompare == PH_FRINFC_MFUL_FMT_VAL_0) { /* Write NDEF TLV in block number 4 */ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_4; /* Card already have the OTP bytes so write TLV */ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_TLV; } else { /* IS the card new, OTP bytes = {0x00, 0x00, 0x00, 0x00} */ memcompare = (uint32_t)MemCompare1(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_4], ZeroBuf, PH_FRINFC_MFUL_FMT_VAL_4); /* If OTP bytes are Zero then the card is Zero */ if (memcompare == PH_FRINFC_MFUL_FMT_VAL_0) { /* Write OTP bytes in block number 3 */ NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock = PH_FRINFC_MFUL_FMT_VAL_3; /* Card already have the OTP bytes so write TLV */ NdefSmtCrdFmt->State = PH_FRINFC_MFUL_FMT_WR_OTPBYTES; } } } if( ((NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_TLV) || (NdefSmtCrdFmt->State == PH_FRINFC_MFUL_FMT_WR_OTPBYTES)) && ((NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD) || (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_UL_CARD)) ) { Result = phFriNfc_MfUL_H_WrRd(NdefSmtCrdFmt); } PH_LOG_NDEF_FUNC_EXIT(); return Result; }
static void phFriNfc_MfUL_H_fillSendBuf( phFriNfc_sNdefSmtCrdFmt_t *NdefSmtCrdFmt, uint8_t BlockNo) { uint8_t NDEFTLV1[4] = {0x01, 0x03, 0xA0, 0x10}; uint8_t NDEFTLV2[4] = {0x44, 0x03, 0x00, 0xFE}; uint8_t NDEFTLV[4] = {0x03, 0x00, 0xFE, 0x00}; PH_LOG_NDEF_FUNC_ENTRY(); /* First byte for send buffer is always the block number */ NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_0] = (uint8_t)BlockNo; switch(NdefSmtCrdFmt->State) { case PH_FRINFC_MFUL_FMT_RO_RD_16BYTES: { NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; *NdefSmtCrdFmt->SendRecvBuf = RD_LOCK_OTP_BLOCK_NUMBER; /* Send length for read command is always one */ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1; break; } case PH_FRINFC_MFUL_FMT_RO_NDEF_PARSE_RD_BYTES: { NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; *NdefSmtCrdFmt->SendRecvBuf = NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock; /* Send length for read command is always one */ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1; break; } case PH_FRINFC_MFUL_FMT_RO_RD_DYN_LOCK_BYTES: { NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; *NdefSmtCrdFmt->SendRecvBuf = NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock; /* Send length for read command is always one */ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1; break; } case PH_FRINFC_MFUL_FMT_RO_WR_DYN_LOCK_BYTES: { NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; /* Send length for read command is always one */ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; *NdefSmtCrdFmt->SendRecvBuf = NdefSmtCrdFmt->AddInfo.Type2Info.CurrentBlock; (void)phOsalNfc_MemCopy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], NdefSmtCrdFmt->AddInfo.Type2Info.DynLockBytes, PH_FRINFC_MFUL_FMT_VAL_4); break; } case PH_FRINFC_MFUL_FMT_RO_WR_LOCK_BYTES: { NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; /* Send length for read command is always one */ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; *NdefSmtCrdFmt->SendRecvBuf = RD_LOCK_OTP_BLOCK_NUMBER; (void)phOsalNfc_MemCopy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], NdefSmtCrdFmt->AddInfo.Type2Info.LockBytes, PH_FRINFC_MFUL_FMT_VAL_4); break; } case PH_FRINFC_MFUL_FMT_RO_WR_OTP_BYTES: { NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; /* Send length for read command is always one */ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; *NdefSmtCrdFmt->SendRecvBuf = OTP_BLOCK_NUMBER; phOsalNfc_MemCopy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, PH_FRINFC_MFUL_FMT_VAL_4); break; } case PH_FRINFC_MFUL_FMT_RD_16BYTES: NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareRead; /* Send length for read command is always one */ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_1; break; case PH_FRINFC_MFUL_FMT_WR_OTPBYTES: /* Send length for read command is always Five */ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; /* Write command */ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; /* Copy the OTP bytes */ phOsalNfc_MemCopy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], NdefSmtCrdFmt->AddInfo.Type2Info.OTPBytes, PH_FRINFC_MFUL_FMT_VAL_4); break; case PH_FRINFC_MFUL_FMT_WR_TLV: /* Send length for read command is always Five */ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; /* Write command */ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; /* Copy the NDEF TLV */ if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD) { phOsalNfc_MemCopy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], NDEFTLV1, PH_FRINFC_MFUL_FMT_VAL_4); } else if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_UL_CARD) { phOsalNfc_MemCopy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], NDEFTLV, PH_FRINFC_MFUL_FMT_VAL_4); } else { } break; case PH_FRINFC_MFUL_FMT_WR_TLV1: if (NdefSmtCrdFmt->CardType == PH_FRINFC_NDEFMAP_MIFARE_ULC_CARD) { /* Send length for write command is always Five */ NdefSmtCrdFmt->SendLength = PH_FRINFC_MFUL_FMT_VAL_5; /* Write command */ NdefSmtCrdFmt->Cmd.MfCmd = phHal_eMifareWrite4; phOsalNfc_MemCopy(&NdefSmtCrdFmt->SendRecvBuf[PH_FRINFC_MFUL_FMT_VAL_1], NDEFTLV2, PH_FRINFC_MFUL_FMT_VAL_4); } break; default: break; } PH_LOG_NDEF_FUNC_EXIT(); }