blob: 9ee49dbc561e03fb8a183ad0853a49fd173b14f7 [file] [log] [blame]
nxp72763946fc382019-11-29 17:30:41 +05301/******************************************************************************
2 *
3 * Copyright 2019 NXP
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 ******************************************************************************/
18#include "NxpMfcReader.h"
anil.hiranniah5eb82022021-03-27 10:33:22 +053019#include <log/log.h>
nxp72763946fc382019-11-29 17:30:41 +053020#include <phNfcCompId.h>
21#include <phNxpLog.h>
22#include <phNxpNciHal_Adaptation.h>
23#include <phNxpNciHal_ext.h>
anil.hiranniah5eb82022021-03-27 10:33:22 +053024#include "phNxpNciHal.h"
nxp72763946fc382019-11-29 17:30:41 +053025
26extern bool sendRspToUpperLayer;
27
anil.hiranniah5eb82022021-03-27 10:33:22 +053028NxpMfcReader& NxpMfcReader::getInstance() {
nxp72763946fc382019-11-29 17:30:41 +053029 static NxpMfcReader msNxpMfcReader;
30 return msNxpMfcReader;
31}
32
33/*******************************************************************************
34**
35** Function Write
36**
37** Description Wrapper API to handle Mifare Transceive to TAG_CMD interface
38** RAW read write.
39**
40** Returns It returns number of bytes successfully written to NFCC.
41**
42*******************************************************************************/
anil.hiranniah5eb82022021-03-27 10:33:22 +053043int NxpMfcReader::Write(uint16_t mfcDataLen, const uint8_t* pMfcData) {
nxp72763946fc382019-11-29 17:30:41 +053044 uint16_t mfcTagCmdBuffLen = 0;
45 uint8_t mfcTagCmdBuff[MAX_MFC_BUFF_SIZE] = {0};
46
Alisher Alikhodjaev4c387792020-10-20 17:20:38 -070047 if (mfcDataLen > MAX_MFC_BUFF_SIZE) {
48 android_errorWriteLog(0x534e4554, "169259605");
49 mfcDataLen = MAX_MFC_BUFF_SIZE;
50 }
nxp72763946fc382019-11-29 17:30:41 +053051 memcpy(mfcTagCmdBuff, pMfcData, mfcDataLen);
anil.hiranniah5eb82022021-03-27 10:33:22 +053052 if (mfcDataLen >= 3) mfcTagCmdBuffLen = mfcDataLen - NCI_HEADER_SIZE;
nxp72763946fc382019-11-29 17:30:41 +053053 BuildMfcCmd(&mfcTagCmdBuff[3], &mfcTagCmdBuffLen);
54
55 mfcTagCmdBuff[2] = mfcTagCmdBuffLen;
Alisher Alikhodjaev8f88d642023-01-31 17:58:00 -080056 int writtenDataLen = phNxpNciHal_write_internal(
57 mfcTagCmdBuffLen + NCI_HEADER_SIZE, mfcTagCmdBuff);
nxp72763946fc382019-11-29 17:30:41 +053058
59 /* send TAG_CMD part 2 for Mifare increment ,decrement and restore commands */
60 if (mfcTagCmdBuff[4] == eMifareDec || mfcTagCmdBuff[4] == eMifareInc ||
61 mfcTagCmdBuff[4] == eMifareRestore) {
Alisher Alikhodjaev8f88d642023-01-31 17:58:00 -080062 SendIncDecRestoreCmdPart2(mfcDataLen, pMfcData);
nxp72763946fc382019-11-29 17:30:41 +053063 }
64 return writtenDataLen;
65}
66
67/*******************************************************************************
68**
69** Function BuildMfcCmd
70**
71** Description builds the TAG CMD for Mifare Classic Tag.
72**
73** Returns None
74**
75*******************************************************************************/
anil.hiranniah5eb82022021-03-27 10:33:22 +053076void NxpMfcReader::BuildMfcCmd(uint8_t* pData, uint16_t* pLength) {
nxp72763946fc382019-11-29 17:30:41 +053077 uint16_t cmdBuffLen = *pLength;
78 memcpy(mMfcTagCmdIntfData.sendBuf, pData, cmdBuffLen);
79 mMfcTagCmdIntfData.sendBufLen = cmdBuffLen;
80
81 switch (pData[0]) {
anil.hiranniah5eb82022021-03-27 10:33:22 +053082 case eMifareAuthentA:
83 case eMifareAuthentB:
84 BuildAuthCmd();
85 break;
86 case eMifareRead16:
87 BuildReadCmd();
88 break;
89 case eMifareWrite16:
90 AuthForWrite();
91 BuildWrite16Cmd();
92 break;
93 case eMifareInc:
94 case eMifareDec:
95 BuildIncDecCmd();
96 break;
97 default:
98 BuildRawCmd();
99 break;
nxp72763946fc382019-11-29 17:30:41 +0530100 }
101
102 memcpy(pData, mMfcTagCmdIntfData.sendBuf, (mMfcTagCmdIntfData.sendBufLen));
103 *pLength = (mMfcTagCmdIntfData.sendBufLen);
104 return;
105}
106
107/*******************************************************************************
108**
109** Function BuildAuthCmd
110**
111** Description builds the TAG CMD for Mifare Auth.
112**
113** Returns None
114**
115*******************************************************************************/
116void NxpMfcReader::BuildAuthCmd() {
117 uint8_t byKey = 0x00, noOfKeys = 0x00;
118 bool isPreloadedKey = false;
119
120 if (mMfcTagCmdIntfData.sendBuf[0] == eMifareAuthentB) {
121 byKey |= MFC_ENABLE_KEY_B;
122 }
123 uint8_t aMfckeys[MFC_NUM_OF_KEYS][MFC_KEY_SIZE] = MFC_KEYS;
124 noOfKeys = sizeof(aMfckeys) / MFC_KEY_SIZE;
125 for (uint8_t byIndex = 0; byIndex < noOfKeys; byIndex++) {
126 if ((memcmp(aMfckeys[byIndex], &mMfcTagCmdIntfData.sendBuf[6],
127 MFC_AUTHKEYLEN) == 0x00)) {
128 byKey = byKey | byIndex;
129 isPreloadedKey = true;
130 break;
131 }
132 }
133 CalcSectorAddress();
134 mMfcTagCmdIntfData.sendBufLen = 0x03;
135 if (!isPreloadedKey) {
136 byKey |= MFC_EMBEDDED_KEY;
Anil Hiranniahbf307e52020-02-20 10:06:38 +0530137 memmove(&mMfcTagCmdIntfData.sendBuf[3], &mMfcTagCmdIntfData.sendBuf[6],
anil.hiranniah5eb82022021-03-27 10:33:22 +0530138 MFC_AUTHKEYLEN);
nxp72763946fc382019-11-29 17:30:41 +0530139 mMfcTagCmdIntfData.sendBufLen += MFC_AUTHKEYLEN;
140 }
141
142 mMfcTagCmdIntfData.sendBuf[0] = eMfcAuthReq;
143 mMfcTagCmdIntfData.sendBuf[1] = mMfcTagCmdIntfData.byAddr;
144 mMfcTagCmdIntfData.sendBuf[2] = byKey;
145 return;
146}
147
148/*******************************************************************************
149**
150** Function CalcSectorAddress
151**
152** Description This function update the sector address for Mifare classic
153**
154** Returns None
155**
156*******************************************************************************/
157void NxpMfcReader::CalcSectorAddress() {
158 uint8_t BlockNumber = mMfcTagCmdIntfData.sendBuf[1];
159 if (BlockNumber >= MFC_4K_BLK128) {
160 mMfcTagCmdIntfData.byAddr =
161 (uint8_t)(MFC_SECTOR_NO32 +
162 ((BlockNumber - MFC_4K_BLK128) / MFC_BYTES_PER_BLOCK));
163 } else {
164 mMfcTagCmdIntfData.byAddr = BlockNumber / MFC_BLKS_PER_SECTOR;
165 }
166
167 return;
168}
169
170/*******************************************************************************
171**
172** Function BuildReadCmd
173**
174** Description builds the TAG CMD for Mifare Read.
175**
176** Returns None
177**
178*******************************************************************************/
179void NxpMfcReader::BuildReadCmd() { BuildRawCmd(); }
180
181/*******************************************************************************
182**
183** Function BuildWrite16Cmd
184**
185** Description builds the TAG CMD for Mifare write part 2.
186**
187** Returns None
188**
189*******************************************************************************/
190void NxpMfcReader::BuildWrite16Cmd() {
191 mMfcTagCmdIntfData.sendBuf[0] = eMfRawDataXchgHdr;
192 mMfcTagCmdIntfData.sendBufLen = mMfcTagCmdIntfData.sendBufLen - 1;
193 memmove(mMfcTagCmdIntfData.sendBuf + 1, mMfcTagCmdIntfData.sendBuf + 2,
194 mMfcTagCmdIntfData.sendBufLen);
195}
196
197/*******************************************************************************
198**
199** Function BuildRawCmd
200**
201** Description builds the TAG CMD for Raw transceive.
202**
203** Returns None
204**
205*******************************************************************************/
206void NxpMfcReader::BuildRawCmd() {
207 mMfcTagCmdIntfData.sendBufLen = mMfcTagCmdIntfData.sendBufLen + 1;
208 memmove(mMfcTagCmdIntfData.sendBuf + 1, mMfcTagCmdIntfData.sendBuf,
209 mMfcTagCmdIntfData.sendBufLen);
210 mMfcTagCmdIntfData.sendBuf[0] = eMfRawDataXchgHdr;
211}
212
213/*******************************************************************************
214**
215** Function BuildIncDecCmd
216**
217** Description builds the TAG CMD for Mifare Inc/Dec.
218**
219** Returns None
220**
221*******************************************************************************/
222void NxpMfcReader::BuildIncDecCmd() {
anil.hiranniah5eb82022021-03-27 10:33:22 +0530223 mMfcTagCmdIntfData.sendBufLen = 0x03; // eMfRawDataXchgHdr + cmd +
224 // blockaddress
nxp72763946fc382019-11-29 17:30:41 +0530225 memmove(mMfcTagCmdIntfData.sendBuf + 1, mMfcTagCmdIntfData.sendBuf,
226 mMfcTagCmdIntfData.sendBufLen);
227 mMfcTagCmdIntfData.sendBuf[0] = eMfRawDataXchgHdr;
228}
229
230/*******************************************************************************
231**
232** Function AuthForWrite
233**
234** Description send Mifare write Part 1.
235**
236** Returns None
237**
238*******************************************************************************/
239void NxpMfcReader::AuthForWrite() {
240 sendRspToUpperLayer = false;
241 NFCSTATUS status = NFCSTATUS_FAILED;
242 uint8_t authForWriteBuff[] = {0x00,
243 0x00,
244 0x03,
245 (uint8_t)eMfRawDataXchgHdr,
246 (uint8_t)mMfcTagCmdIntfData.sendBuf[0],
247 (uint8_t)mMfcTagCmdIntfData.sendBuf[1]};
248
249 status = phNxpNciHal_send_ext_cmd(
250 sizeof(authForWriteBuff) / sizeof(authForWriteBuff[0]), authForWriteBuff);
251 if (status != NFCSTATUS_SUCCESS) {
252 NXPLOG_NCIHAL_E("Mifare Auth for Transceive failed");
253 }
254 return;
255}
256
257/*******************************************************************************
258**
259** Function SendIncDecRestoreCmdPart2
260**
261** Description send Mifare Inc/Dec/Restore Command Part 2.
262**
263** Returns None
264**
265*******************************************************************************/
Alisher Alikhodjaev8f88d642023-01-31 17:58:00 -0800266void NxpMfcReader::SendIncDecRestoreCmdPart2(uint16_t mfcDataLen,
267 const uint8_t* mfcData) {
nxp72763946fc382019-11-29 17:30:41 +0530268 NFCSTATUS status = NFCSTATUS_SUCCESS;
269 /* Build TAG_CMD part 2 for Mifare increment ,decrement and restore commands*/
270 uint8_t incDecRestorePart2[] = {0x00, 0x00, 0x05, (uint8_t)eMfRawDataXchgHdr,
271 0x00, 0x00, 0x00, 0x00};
272 uint8_t incDecRestorePart2Size =
273 (sizeof(incDecRestorePart2) / sizeof(incDecRestorePart2[0]));
274 if (mfcData[3] == eMifareInc || mfcData[3] == eMifareDec) {
Alisher Alikhodjaev8f88d642023-01-31 17:58:00 -0800275 if (incDecRestorePart2Size >= mfcDataLen) {
276 incDecRestorePart2Size = mfcDataLen - 1;
277 android_errorWriteLog(0x534e4554, "238177877");
278 }
nxp72763946fc382019-11-29 17:30:41 +0530279 for (int i = 4; i < incDecRestorePart2Size; i++) {
280 incDecRestorePart2[i] = mfcData[i + 1];
281 }
282 }
283 sendRspToUpperLayer = false;
284 status = phNxpNciHal_send_ext_cmd(incDecRestorePart2Size, incDecRestorePart2);
285 if (status != NFCSTATUS_SUCCESS) {
286 NXPLOG_NCIHAL_E("Mifare Cmd for inc/dec/Restore part 2 failed");
287 }
288 return;
289}
290
291/*******************************************************************************
292**
293** Function AnalyzeMfcResp
294**
295** Description Analyze type of MFC response and build MFC response from
296** Tag cmd Intf response?
297**
298** Returns NFCSTATUS_SUCCESS - Data Reception is successful
299** NFCSTATUS_FAILED - Data Reception failed
300**
301*******************************************************************************/
anil.hiranniah5eb82022021-03-27 10:33:22 +0530302NFCSTATUS NxpMfcReader::AnalyzeMfcResp(uint8_t* pBuff, uint16_t* pBufflen) {
nxp72763946fc382019-11-29 17:30:41 +0530303 NFCSTATUS status = NFCSTATUS_SUCCESS;
304 uint16_t wPldDataSize = 0;
305 MfcRespId_t RecvdExtnRspId = eInvalidRsp;
306
307 if (0 == (*pBufflen)) {
308 status = NFCSTATUS_FAILED;
309 } else {
310 RecvdExtnRspId = (MfcRespId_t)pBuff[0];
311 NXPLOG_NCIHAL_E("%s: RecvdExtnRspId=%d", __func__, RecvdExtnRspId);
312 switch (RecvdExtnRspId) {
anil.hiranniah5eb82022021-03-27 10:33:22 +0530313 case eMfXchgDataRsp: {
314 NFCSTATUS writeRespStatus = NFCSTATUS_SUCCESS;
315 /* check the status byte */
316 if (*pBufflen == 3) {
317 if ((pBuff[0] == 0x10) && (pBuff[1] != 0x0A)) {
318 NXPLOG_NCIHAL_E("Mifare Error in payload response");
319 *pBufflen = 0x1;
320 pBuff[0] = NFCSTATUS_FAILED;
321 return NFCSTATUS_FAILED;
322 } else {
323 pBuff[0] = NFCSTATUS_SUCCESS;
324 return NFCSTATUS_SUCCESS;
325 }
nxp72763946fc382019-11-29 17:30:41 +0530326 }
anil.hiranniah5eb82022021-03-27 10:33:22 +0530327 writeRespStatus = pBuff[*pBufflen - 1];
nxp72763946fc382019-11-29 17:30:41 +0530328
anil.hiranniah5eb82022021-03-27 10:33:22 +0530329 if (NFCSTATUS_SUCCESS == writeRespStatus) {
330 status = NFCSTATUS_SUCCESS;
331 uint16_t wRecvDataSz = 0;
nxp72763946fc382019-11-29 17:30:41 +0530332
anil.hiranniah5eb82022021-03-27 10:33:22 +0530333 wPldDataSize =
334 ((*pBufflen) - (MFC_EXTN_ID_SIZE + MFC_EXTN_STATUS_SIZE));
335 wRecvDataSz = MAX_MFC_BUFF_SIZE;
336 if ((wPldDataSize) <= wRecvDataSz) {
337 /* Extract the data part from pBuff[2] & fill it to be sent to
338 * upper layer */
339 memmove(&(pBuff[0]), &(pBuff[1]), wPldDataSize);
340 /* update the number of bytes received from lower layer,excluding
341 * the status byte */
342 *pBufflen = wPldDataSize;
343 } else {
344 status = NFCSTATUS_FAILED;
345 }
nxp72763946fc382019-11-29 17:30:41 +0530346 } else {
347 status = NFCSTATUS_FAILED;
348 }
anil.hiranniah5eb82022021-03-27 10:33:22 +0530349 } break;
nxp72763946fc382019-11-29 17:30:41 +0530350
anil.hiranniah5eb82022021-03-27 10:33:22 +0530351 case eMfcAuthRsp: {
Alisher Alikhodjaev10a70012023-03-01 13:00:03 -0800352 if (*pBufflen < 2) {
353 status = NFCSTATUS_FAILED;
354 break;
355 }
anil.hiranniah5eb82022021-03-27 10:33:22 +0530356 /* check the status byte */
357 if (NFCSTATUS_SUCCESS == pBuff[1]) {
358 status = NFCSTATUS_SUCCESS;
359 /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */
360 wPldDataSize =
361 ((*pBufflen) - (MFC_EXTN_ID_SIZE + MFC_EXTN_STATUS_SIZE));
362 /* Extract the data part from pBuff[2] & fill it to be sent to upper
363 * layer */
364 pBuff[0] = pBuff[1];
365 /* update the number of bytes received from lower layer,excluding
366 * the status byte */
367 *pBufflen = wPldDataSize + 1;
368 } else {
369 pBuff[0] = pBuff[1];
370 *pBufflen = 1;
371 status = NFCSTATUS_FAILED;
372 }
373 } break;
374 default: {
nxp72763946fc382019-11-29 17:30:41 +0530375 status = NFCSTATUS_FAILED;
anil.hiranniah5eb82022021-03-27 10:33:22 +0530376 } break;
nxp72763946fc382019-11-29 17:30:41 +0530377 }
378 }
379 return status;
380}
381
382/*******************************************************************************
383**
384** Function CheckMfcResponse
385**
386** Description This function is called to check if it's a valid Mfc
387** response data
388**
389** Returns NFCSTATUS_SUCCESS
390** NFCSTATUS_FAILED
391**
392*******************************************************************************/
anil.hiranniah5eb82022021-03-27 10:33:22 +0530393NFCSTATUS NxpMfcReader::CheckMfcResponse(uint8_t* pTransceiveData,
nxp72763946fc382019-11-29 17:30:41 +0530394 uint16_t transceiveDataLen) {
395 NFCSTATUS status = NFCSTATUS_SUCCESS;
396
397 if (transceiveDataLen == 3) {
398 if ((pTransceiveData)[0] == 0x10 && (pTransceiveData)[1] != 0x0A) {
399 NXPLOG_NCIHAL_E("Mifare Error in payload response");
400 transceiveDataLen = 0x1;
401 pTransceiveData += 1;
402 return NFCSTATUS_FAILED;
403 }
404 }
405 if ((pTransceiveData)[0] == 0x40) {
406 pTransceiveData += 1;
407 transceiveDataLen = 0x01;
408 if ((pTransceiveData)[0] == 0x03) {
409 transceiveDataLen = 0x00;
410 status = NFCSTATUS_FAILED;
411 }
412 } else if ((pTransceiveData)[0] == 0x10) {
413 pTransceiveData += 1;
414 transceiveDataLen = 0x10;
415 }
416 return status;
417}