nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 1 | /****************************************************************************** |
| 2 | * |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 3 | * Copyright 2019-2021 NXP |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 4 | * |
| 5 | * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | * you may not use this file except in compliance with the License. |
| 7 | * You may obtain a copy of the License at |
| 8 | * |
| 9 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 10 | * |
| 11 | * Unless required by applicable law or agreed to in writing, software |
| 12 | * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | * See the License for the specific language governing permissions and |
| 15 | * limitations under the License. |
| 16 | * |
| 17 | ******************************************************************************/ |
George Chang | f21544f | 2021-05-13 05:38:02 +0000 | [diff] [blame] | 18 | #include "NxpMfcReader.h" |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 19 | #include <phNfcCompId.h> |
| 20 | #include <phNxpLog.h> |
| 21 | #include <phNxpNciHal_Adaptation.h> |
| 22 | #include <phNxpNciHal_ext.h> |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 23 | #include "phNxpNciHal.h" |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 24 | |
| 25 | extern bool sendRspToUpperLayer; |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 26 | extern bool bEnableMfcExtns; |
| 27 | extern bool bDisableLegacyMfcExtns; |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 28 | |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 29 | NxpMfcReader& NxpMfcReader::getInstance() { |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 30 | static NxpMfcReader msNxpMfcReader; |
| 31 | return msNxpMfcReader; |
| 32 | } |
| 33 | |
| 34 | /******************************************************************************* |
| 35 | ** |
| 36 | ** Function Write |
| 37 | ** |
| 38 | ** Description Wrapper API to handle Mifare Transceive to TAG_CMD interface |
| 39 | ** RAW read write. |
| 40 | ** |
| 41 | ** Returns It returns number of bytes successfully written to NFCC. |
| 42 | ** |
| 43 | *******************************************************************************/ |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 44 | int NxpMfcReader::Write(uint16_t mfcDataLen, const uint8_t* pMfcData) { |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 45 | uint16_t mfcTagCmdBuffLen = 0; |
| 46 | uint8_t mfcTagCmdBuff[MAX_MFC_BUFF_SIZE] = {0}; |
| 47 | |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 48 | if (mfcDataLen > MAX_MFC_BUFF_SIZE) { |
| 49 | android_errorWriteLog(0x534e4554, "169259605"); |
| 50 | mfcDataLen = MAX_MFC_BUFF_SIZE; |
| 51 | } |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 52 | memcpy(mfcTagCmdBuff, pMfcData, mfcDataLen); |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 53 | if (mfcDataLen >= 3) mfcTagCmdBuffLen = mfcDataLen - NCI_HEADER_SIZE; |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 54 | BuildMfcCmd(&mfcTagCmdBuff[3], &mfcTagCmdBuffLen); |
| 55 | |
| 56 | mfcTagCmdBuff[2] = mfcTagCmdBuffLen; |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 57 | |
| 58 | if (checkIsMFCIncDecRestore(pMfcData[3])) { |
| 59 | if (sem_init(&mNacksem, 0, 0) != 0) { |
| 60 | NXPLOG_NCIHAL_E("%s : sem_init failed", __func__); |
| 61 | return 0; |
| 62 | } |
| 63 | } |
Alisher Alikhodjaev | 8f88d64 | 2023-01-31 17:58:00 -0800 | [diff] [blame] | 64 | int writtenDataLen = phNxpNciHal_write_internal( |
| 65 | mfcTagCmdBuffLen + NCI_HEADER_SIZE, mfcTagCmdBuff); |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 66 | |
| 67 | /* send TAG_CMD part 2 for Mifare increment ,decrement and restore commands */ |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 68 | if (checkIsMFCIncDecRestore(pMfcData[3])) { |
| 69 | MfcWaitForAck(); |
| 70 | if (isAck) { |
| 71 | NXPLOG_NCIHAL_D("part 1 command Acked"); |
Alisher Alikhodjaev | 8f88d64 | 2023-01-31 17:58:00 -0800 | [diff] [blame] | 72 | SendIncDecRestoreCmdPart2(mfcDataLen, pMfcData); |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 73 | } else { |
| 74 | NXPLOG_NCIHAL_E("part 1 command NACK"); |
| 75 | } |
| 76 | sem_destroy(&mNacksem); |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 77 | } |
| 78 | return writtenDataLen; |
| 79 | } |
| 80 | |
| 81 | /******************************************************************************* |
| 82 | ** |
| 83 | ** Function BuildMfcCmd |
| 84 | ** |
| 85 | ** Description builds the TAG CMD for Mifare Classic Tag. |
| 86 | ** |
| 87 | ** Returns None |
| 88 | ** |
| 89 | *******************************************************************************/ |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 90 | void NxpMfcReader::BuildMfcCmd(uint8_t* pData, uint16_t* pLength) { |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 91 | uint16_t cmdBuffLen = *pLength; |
| 92 | memcpy(mMfcTagCmdIntfData.sendBuf, pData, cmdBuffLen); |
| 93 | mMfcTagCmdIntfData.sendBufLen = cmdBuffLen; |
| 94 | |
| 95 | switch (pData[0]) { |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 96 | case eMifareAuthentA: |
| 97 | case eMifareAuthentB: |
| 98 | BuildAuthCmd(); |
| 99 | break; |
| 100 | case eMifareRead16: |
| 101 | BuildReadCmd(); |
| 102 | break; |
| 103 | case eMifareWrite16: |
| 104 | AuthForWrite(); |
| 105 | BuildWrite16Cmd(); |
| 106 | break; |
| 107 | case eMifareInc: |
| 108 | case eMifareDec: |
| 109 | BuildIncDecCmd(); |
| 110 | break; |
| 111 | default: |
| 112 | BuildRawCmd(); |
| 113 | break; |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 114 | } |
| 115 | |
| 116 | memcpy(pData, mMfcTagCmdIntfData.sendBuf, (mMfcTagCmdIntfData.sendBufLen)); |
| 117 | *pLength = (mMfcTagCmdIntfData.sendBufLen); |
| 118 | return; |
| 119 | } |
| 120 | |
| 121 | /******************************************************************************* |
| 122 | ** |
| 123 | ** Function BuildAuthCmd |
| 124 | ** |
| 125 | ** Description builds the TAG CMD for Mifare Auth. |
| 126 | ** |
| 127 | ** Returns None |
| 128 | ** |
| 129 | *******************************************************************************/ |
| 130 | void NxpMfcReader::BuildAuthCmd() { |
| 131 | uint8_t byKey = 0x00, noOfKeys = 0x00; |
| 132 | bool isPreloadedKey = false; |
| 133 | |
| 134 | if (mMfcTagCmdIntfData.sendBuf[0] == eMifareAuthentB) { |
| 135 | byKey |= MFC_ENABLE_KEY_B; |
| 136 | } |
| 137 | uint8_t aMfckeys[MFC_NUM_OF_KEYS][MFC_KEY_SIZE] = MFC_KEYS; |
| 138 | noOfKeys = sizeof(aMfckeys) / MFC_KEY_SIZE; |
| 139 | for (uint8_t byIndex = 0; byIndex < noOfKeys; byIndex++) { |
| 140 | if ((memcmp(aMfckeys[byIndex], &mMfcTagCmdIntfData.sendBuf[6], |
| 141 | MFC_AUTHKEYLEN) == 0x00)) { |
| 142 | byKey = byKey | byIndex; |
| 143 | isPreloadedKey = true; |
| 144 | break; |
| 145 | } |
| 146 | } |
| 147 | CalcSectorAddress(); |
| 148 | mMfcTagCmdIntfData.sendBufLen = 0x03; |
| 149 | if (!isPreloadedKey) { |
| 150 | byKey |= MFC_EMBEDDED_KEY; |
Anil Hiranniah | bf307e5 | 2020-02-20 10:06:38 +0530 | [diff] [blame] | 151 | memmove(&mMfcTagCmdIntfData.sendBuf[3], &mMfcTagCmdIntfData.sendBuf[6], |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 152 | MFC_AUTHKEYLEN); |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 153 | mMfcTagCmdIntfData.sendBufLen += MFC_AUTHKEYLEN; |
| 154 | } |
| 155 | |
| 156 | mMfcTagCmdIntfData.sendBuf[0] = eMfcAuthReq; |
| 157 | mMfcTagCmdIntfData.sendBuf[1] = mMfcTagCmdIntfData.byAddr; |
| 158 | mMfcTagCmdIntfData.sendBuf[2] = byKey; |
| 159 | return; |
| 160 | } |
| 161 | |
| 162 | /******************************************************************************* |
| 163 | ** |
| 164 | ** Function CalcSectorAddress |
| 165 | ** |
| 166 | ** Description This function update the sector address for Mifare classic |
| 167 | ** |
| 168 | ** Returns None |
| 169 | ** |
| 170 | *******************************************************************************/ |
| 171 | void NxpMfcReader::CalcSectorAddress() { |
| 172 | uint8_t BlockNumber = mMfcTagCmdIntfData.sendBuf[1]; |
| 173 | if (BlockNumber >= MFC_4K_BLK128) { |
| 174 | mMfcTagCmdIntfData.byAddr = |
| 175 | (uint8_t)(MFC_SECTOR_NO32 + |
| 176 | ((BlockNumber - MFC_4K_BLK128) / MFC_BYTES_PER_BLOCK)); |
| 177 | } else { |
| 178 | mMfcTagCmdIntfData.byAddr = BlockNumber / MFC_BLKS_PER_SECTOR; |
| 179 | } |
| 180 | |
| 181 | return; |
| 182 | } |
| 183 | |
| 184 | /******************************************************************************* |
| 185 | ** |
| 186 | ** Function BuildReadCmd |
| 187 | ** |
| 188 | ** Description builds the TAG CMD for Mifare Read. |
| 189 | ** |
| 190 | ** Returns None |
| 191 | ** |
| 192 | *******************************************************************************/ |
| 193 | void NxpMfcReader::BuildReadCmd() { BuildRawCmd(); } |
| 194 | |
| 195 | /******************************************************************************* |
| 196 | ** |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 197 | ** Function checkIsMFCIncDecRestore |
| 198 | ** |
| 199 | ** Description Check command is MF Increment/Decrement or Restore. |
| 200 | ** |
| 201 | ** Returns True/False |
| 202 | ** |
| 203 | *******************************************************************************/ |
| 204 | bool NxpMfcReader::checkIsMFCIncDecRestore(uint8_t cmdInst) { |
| 205 | return (cmdInst == eMifareDec || cmdInst == eMifareInc || |
| 206 | cmdInst == eMifareRestore); |
| 207 | } |
| 208 | |
| 209 | /******************************************************************************* |
| 210 | ** |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 211 | ** Function BuildWrite16Cmd |
| 212 | ** |
| 213 | ** Description builds the TAG CMD for Mifare write part 2. |
| 214 | ** |
| 215 | ** Returns None |
| 216 | ** |
| 217 | *******************************************************************************/ |
| 218 | void NxpMfcReader::BuildWrite16Cmd() { |
| 219 | mMfcTagCmdIntfData.sendBuf[0] = eMfRawDataXchgHdr; |
| 220 | mMfcTagCmdIntfData.sendBufLen = mMfcTagCmdIntfData.sendBufLen - 1; |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 221 | uint8_t buff[mMfcTagCmdIntfData.sendBufLen]; |
| 222 | memset(buff, 0, mMfcTagCmdIntfData.sendBufLen); |
| 223 | memcpy(buff, mMfcTagCmdIntfData.sendBuf + 2, mMfcTagCmdIntfData.sendBufLen); |
| 224 | memcpy(mMfcTagCmdIntfData.sendBuf + 1, buff, mMfcTagCmdIntfData.sendBufLen); |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 225 | } |
| 226 | |
| 227 | /******************************************************************************* |
| 228 | ** |
| 229 | ** Function BuildRawCmd |
| 230 | ** |
| 231 | ** Description builds the TAG CMD for Raw transceive. |
| 232 | ** |
| 233 | ** Returns None |
| 234 | ** |
| 235 | *******************************************************************************/ |
| 236 | void NxpMfcReader::BuildRawCmd() { |
| 237 | mMfcTagCmdIntfData.sendBufLen = mMfcTagCmdIntfData.sendBufLen + 1; |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 238 | uint8_t buff[mMfcTagCmdIntfData.sendBufLen]; |
| 239 | memset(buff, 0, mMfcTagCmdIntfData.sendBufLen); |
| 240 | memcpy(buff, mMfcTagCmdIntfData.sendBuf, mMfcTagCmdIntfData.sendBufLen); |
| 241 | memcpy(mMfcTagCmdIntfData.sendBuf + 1, buff, mMfcTagCmdIntfData.sendBufLen); |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 242 | mMfcTagCmdIntfData.sendBuf[0] = eMfRawDataXchgHdr; |
| 243 | } |
| 244 | |
| 245 | /******************************************************************************* |
| 246 | ** |
| 247 | ** Function BuildIncDecCmd |
| 248 | ** |
| 249 | ** Description builds the TAG CMD for Mifare Inc/Dec. |
| 250 | ** |
| 251 | ** Returns None |
| 252 | ** |
| 253 | *******************************************************************************/ |
| 254 | void NxpMfcReader::BuildIncDecCmd() { |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 255 | mMfcTagCmdIntfData.sendBufLen = 0x03; // eMfRawDataXchgHdr + cmd + |
| 256 | // blockaddress |
| 257 | uint8_t buff[mMfcTagCmdIntfData.sendBufLen]; |
| 258 | memset(buff, 0, mMfcTagCmdIntfData.sendBufLen); |
| 259 | memcpy(buff, mMfcTagCmdIntfData.sendBuf, mMfcTagCmdIntfData.sendBufLen); |
| 260 | memcpy(mMfcTagCmdIntfData.sendBuf + 1, buff, mMfcTagCmdIntfData.sendBufLen); |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 261 | mMfcTagCmdIntfData.sendBuf[0] = eMfRawDataXchgHdr; |
| 262 | } |
| 263 | |
| 264 | /******************************************************************************* |
| 265 | ** |
| 266 | ** Function AuthForWrite |
| 267 | ** |
| 268 | ** Description send Mifare write Part 1. |
| 269 | ** |
| 270 | ** Returns None |
| 271 | ** |
| 272 | *******************************************************************************/ |
| 273 | void NxpMfcReader::AuthForWrite() { |
| 274 | sendRspToUpperLayer = false; |
| 275 | NFCSTATUS status = NFCSTATUS_FAILED; |
| 276 | uint8_t authForWriteBuff[] = {0x00, |
| 277 | 0x00, |
| 278 | 0x03, |
| 279 | (uint8_t)eMfRawDataXchgHdr, |
| 280 | (uint8_t)mMfcTagCmdIntfData.sendBuf[0], |
| 281 | (uint8_t)mMfcTagCmdIntfData.sendBuf[1]}; |
| 282 | |
| 283 | status = phNxpNciHal_send_ext_cmd( |
| 284 | sizeof(authForWriteBuff) / sizeof(authForWriteBuff[0]), authForWriteBuff); |
| 285 | if (status != NFCSTATUS_SUCCESS) { |
| 286 | NXPLOG_NCIHAL_E("Mifare Auth for Transceive failed"); |
| 287 | } |
| 288 | return; |
| 289 | } |
| 290 | |
| 291 | /******************************************************************************* |
| 292 | ** |
| 293 | ** Function SendIncDecRestoreCmdPart2 |
| 294 | ** |
| 295 | ** Description send Mifare Inc/Dec/Restore Command Part 2. |
| 296 | ** |
| 297 | ** Returns None |
| 298 | ** |
| 299 | *******************************************************************************/ |
Alisher Alikhodjaev | 8f88d64 | 2023-01-31 17:58:00 -0800 | [diff] [blame] | 300 | void NxpMfcReader::SendIncDecRestoreCmdPart2(uint16_t mfcDataLen, |
| 301 | const uint8_t* mfcData) { |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 302 | NFCSTATUS status = NFCSTATUS_SUCCESS; |
| 303 | /* Build TAG_CMD part 2 for Mifare increment ,decrement and restore commands*/ |
| 304 | uint8_t incDecRestorePart2[] = {0x00, 0x00, 0x05, (uint8_t)eMfRawDataXchgHdr, |
| 305 | 0x00, 0x00, 0x00, 0x00}; |
| 306 | uint8_t incDecRestorePart2Size = |
| 307 | (sizeof(incDecRestorePart2) / sizeof(incDecRestorePart2[0])); |
| 308 | if (mfcData[3] == eMifareInc || mfcData[3] == eMifareDec) { |
Alisher Alikhodjaev | 8f88d64 | 2023-01-31 17:58:00 -0800 | [diff] [blame] | 309 | if (incDecRestorePart2Size >= mfcDataLen) { |
| 310 | incDecRestorePart2Size = mfcDataLen - 1; |
| 311 | android_errorWriteLog(0x534e4554, "238177877"); |
| 312 | } |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 313 | for (int i = 4; i < incDecRestorePart2Size; i++) { |
| 314 | incDecRestorePart2[i] = mfcData[i + 1]; |
| 315 | } |
| 316 | } |
| 317 | sendRspToUpperLayer = false; |
| 318 | status = phNxpNciHal_send_ext_cmd(incDecRestorePart2Size, incDecRestorePart2); |
| 319 | if (status != NFCSTATUS_SUCCESS) { |
| 320 | NXPLOG_NCIHAL_E("Mifare Cmd for inc/dec/Restore part 2 failed"); |
| 321 | } |
| 322 | return; |
| 323 | } |
| 324 | |
| 325 | /******************************************************************************* |
| 326 | ** |
| 327 | ** Function AnalyzeMfcResp |
| 328 | ** |
| 329 | ** Description Analyze type of MFC response and build MFC response from |
| 330 | ** Tag cmd Intf response? |
| 331 | ** |
| 332 | ** Returns NFCSTATUS_SUCCESS - Data Reception is successful |
| 333 | ** NFCSTATUS_FAILED - Data Reception failed |
| 334 | ** |
| 335 | *******************************************************************************/ |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 336 | NFCSTATUS NxpMfcReader::AnalyzeMfcResp(uint8_t* pBuff, uint16_t* pBufflen) { |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 337 | NFCSTATUS status = NFCSTATUS_SUCCESS; |
| 338 | uint16_t wPldDataSize = 0; |
| 339 | MfcRespId_t RecvdExtnRspId = eInvalidRsp; |
| 340 | |
| 341 | if (0 == (*pBufflen)) { |
| 342 | status = NFCSTATUS_FAILED; |
| 343 | } else { |
| 344 | RecvdExtnRspId = (MfcRespId_t)pBuff[0]; |
| 345 | NXPLOG_NCIHAL_E("%s: RecvdExtnRspId=%d", __func__, RecvdExtnRspId); |
| 346 | switch (RecvdExtnRspId) { |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 347 | case eMfXchgDataRsp: { |
| 348 | NFCSTATUS writeRespStatus = NFCSTATUS_SUCCESS; |
| 349 | /* check the status byte */ |
| 350 | if (*pBufflen == 3) { |
| 351 | if ((pBuff[0] == 0x10) && (pBuff[1] != 0x0A)) { |
| 352 | NXPLOG_NCIHAL_E("Mifare Error in payload response"); |
| 353 | *pBufflen = 0x1; |
| 354 | pBuff[0] = NFCSTATUS_FAILED; |
| 355 | return NFCSTATUS_FAILED; |
| 356 | } else { |
| 357 | pBuff[0] = NFCSTATUS_SUCCESS; |
| 358 | return NFCSTATUS_SUCCESS; |
| 359 | } |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 360 | } |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 361 | writeRespStatus = pBuff[*pBufflen - 1]; |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 362 | |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 363 | if (NFCSTATUS_SUCCESS == writeRespStatus) { |
| 364 | status = NFCSTATUS_SUCCESS; |
| 365 | uint16_t wRecvDataSz = 0; |
George Chang | f21544f | 2021-05-13 05:38:02 +0000 | [diff] [blame] | 366 | |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 367 | wPldDataSize = |
| 368 | ((*pBufflen) - (MFC_EXTN_ID_SIZE + MFC_EXTN_STATUS_SIZE)); |
| 369 | wRecvDataSz = MAX_MFC_BUFF_SIZE; |
| 370 | if ((wPldDataSize) <= wRecvDataSz) { |
| 371 | /* Extract the data part from pBuff[2] & fill it to be sent to |
| 372 | * upper layer */ |
| 373 | memcpy(&(pBuff[0]), &(pBuff[1]), wPldDataSize); |
| 374 | /* update the number of bytes received from lower layer,excluding |
| 375 | * the status byte */ |
| 376 | *pBufflen = wPldDataSize; |
| 377 | } else { |
| 378 | status = NFCSTATUS_FAILED; |
| 379 | } |
anil.hiranniah | 5c4c40d | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 380 | } else { |
anil.hiranniah | 5c4c40d | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 381 | status = NFCSTATUS_FAILED; |
| 382 | } |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 383 | } break; |
George Chang | f21544f | 2021-05-13 05:38:02 +0000 | [diff] [blame] | 384 | |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 385 | case eMfcAuthRsp: { |
Alisher Alikhodjaev | 10a7001 | 2023-03-01 13:00:03 -0800 | [diff] [blame] | 386 | if (*pBufflen < 2) { |
| 387 | status = NFCSTATUS_FAILED; |
| 388 | break; |
| 389 | } |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 390 | /* check the status byte */ |
| 391 | if (NFCSTATUS_SUCCESS == pBuff[1]) { |
| 392 | status = NFCSTATUS_SUCCESS; |
| 393 | /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */ |
| 394 | wPldDataSize = |
| 395 | ((*pBufflen) - (MFC_EXTN_ID_SIZE + MFC_EXTN_STATUS_SIZE)); |
| 396 | /* Extract the data part from pBuff[2] & fill it to be sent to upper |
| 397 | * layer */ |
| 398 | pBuff[0] = pBuff[1]; |
| 399 | /* update the number of bytes received from lower layer,excluding |
| 400 | * the status byte */ |
| 401 | *pBufflen = wPldDataSize + 1; |
| 402 | } else { |
| 403 | pBuff[0] = pBuff[1]; |
| 404 | *pBufflen = 1; |
| 405 | status = NFCSTATUS_FAILED; |
| 406 | } |
| 407 | } break; |
| 408 | default: { |
George Chang | f21544f | 2021-05-13 05:38:02 +0000 | [diff] [blame] | 409 | status = NFCSTATUS_FAILED; |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 410 | } break; |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 411 | } |
| 412 | } |
| 413 | return status; |
| 414 | } |
| 415 | |
| 416 | /******************************************************************************* |
| 417 | ** |
| 418 | ** Function CheckMfcResponse |
| 419 | ** |
| 420 | ** Description This function is called to check if it's a valid Mfc |
| 421 | ** response data |
| 422 | ** |
| 423 | ** Returns NFCSTATUS_SUCCESS |
| 424 | ** NFCSTATUS_FAILED |
| 425 | ** |
| 426 | *******************************************************************************/ |
anil.hiranniah | f05c398 | 2021-03-27 10:33:22 +0530 | [diff] [blame] | 427 | NFCSTATUS NxpMfcReader::CheckMfcResponse(uint8_t* pTransceiveData, |
nxp72763 | 946fc38 | 2019-11-29 17:30:41 +0530 | [diff] [blame] | 428 | uint16_t transceiveDataLen) { |
| 429 | NFCSTATUS status = NFCSTATUS_SUCCESS; |
| 430 | |
| 431 | if (transceiveDataLen == 3) { |
| 432 | if ((pTransceiveData)[0] == 0x10 && (pTransceiveData)[1] != 0x0A) { |
| 433 | NXPLOG_NCIHAL_E("Mifare Error in payload response"); |
| 434 | transceiveDataLen = 0x1; |
| 435 | pTransceiveData += 1; |
| 436 | return NFCSTATUS_FAILED; |
| 437 | } |
| 438 | } |
| 439 | if ((pTransceiveData)[0] == 0x40) { |
| 440 | pTransceiveData += 1; |
| 441 | transceiveDataLen = 0x01; |
| 442 | if ((pTransceiveData)[0] == 0x03) { |
| 443 | transceiveDataLen = 0x00; |
| 444 | status = NFCSTATUS_FAILED; |
| 445 | } |
| 446 | } else if ((pTransceiveData)[0] == 0x10) { |
| 447 | pTransceiveData += 1; |
| 448 | transceiveDataLen = 0x10; |
| 449 | } |
| 450 | return status; |
| 451 | } |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 452 | |
| 453 | /******************************************************************************* |
| 454 | ** |
| 455 | ** Function MfcAckReceived |
| 456 | ** |
| 457 | ** Description This function is called to notify that MFC |
| 458 | ** response data is received |
| 459 | ** |
| 460 | ** Returns NFCSTATUS_SUCCESS |
| 461 | ** NFCSTATUS_FAILED |
| 462 | ** |
| 463 | *******************************************************************************/ |
| 464 | void NxpMfcReader::MfcNotifyOnAckReceived(uint8_t* buff) { |
| 465 | const uint8_t NCI_RF_CONN_ID = 0; |
| 466 | /* |
| 467 | * If Mifare Activated & received RF data packet |
| 468 | */ |
| 469 | if (bEnableMfcExtns && bDisableLegacyMfcExtns && |
| 470 | (buff[0] == NCI_RF_CONN_ID)) { |
| 471 | int sem_val; |
| 472 | isAck = (buff[3] == NFCSTATUS_SUCCESS); |
| 473 | sem_getvalue(&mNacksem, &sem_val); |
| 474 | if (sem_val == 0) { |
| 475 | if (sem_post(&mNacksem) == -1) { |
| 476 | NXPLOG_NCIHAL_E("%s : sem_post failed", __func__); |
| 477 | } |
| 478 | } |
| 479 | } |
| 480 | } |
| 481 | |
| 482 | /******************************************************************************* |
| 483 | ** |
| 484 | ** Function MfcWaitForAck |
| 485 | ** |
| 486 | ** Description This function is called to wait for MFC NACK |
| 487 | ** |
| 488 | ** Returns NFCSTATUS_SUCCESS |
| 489 | ** NFCSTATUS_FAILED |
| 490 | ** |
| 491 | *******************************************************************************/ |
| 492 | NFCSTATUS NxpMfcReader::MfcWaitForAck() { |
| 493 | NFCSTATUS status = NFCSTATUS_FAILED; |
| 494 | int sem_timedout = 2, s; |
| 495 | struct timespec ts; |
| 496 | isAck = false; |
Keith Mok | 783e0e5 | 2022-01-25 18:50:02 +0000 | [diff] [blame] | 497 | clock_gettime(CLOCK_MONOTONIC, &ts); |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 498 | ts.tv_sec += sem_timedout; |
Keith Mok | 783e0e5 | 2022-01-25 18:50:02 +0000 | [diff] [blame] | 499 | while ((s = sem_timedwait_monotonic_np(&mNacksem, &ts)) == -1 && errno == EINTR) { |
anil.hiranniah | a6c1328 | 2021-12-17 17:27:18 +0530 | [diff] [blame] | 500 | continue; /* Restart if interrupted by handler */ |
| 501 | } |
| 502 | if (s != -1) { |
| 503 | status = NFCSTATUS_SUCCESS; |
| 504 | } |
| 505 | return status; |
| 506 | } |