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