1 /******************************************************************************
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 <log/log.h>
20 #include <phNfcCompId.h>
21 #include <phNxpLog.h>
22 #include <phNxpNciHal_Adaptation.h>
23 #include <phNxpNciHal_ext.h>
24 #include "phNxpNciHal.h"
25
26 extern bool sendRspToUpperLayer;
27
getInstance()28 NxpMfcReader& NxpMfcReader::getInstance() {
29 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 *******************************************************************************/
Write(uint16_t mfcDataLen,const uint8_t * pMfcData)43 int NxpMfcReader::Write(uint16_t mfcDataLen, const uint8_t* pMfcData) {
44 uint16_t mfcTagCmdBuffLen = 0;
45 uint8_t mfcTagCmdBuff[MAX_MFC_BUFF_SIZE] = {0};
46
47 if (mfcDataLen > MAX_MFC_BUFF_SIZE) {
48 android_errorWriteLog(0x534e4554, "169259605");
49 mfcDataLen = MAX_MFC_BUFF_SIZE;
50 }
51 memcpy(mfcTagCmdBuff, pMfcData, mfcDataLen);
52 if (mfcDataLen >= 3) mfcTagCmdBuffLen = mfcDataLen - NCI_HEADER_SIZE;
53 BuildMfcCmd(&mfcTagCmdBuff[3], &mfcTagCmdBuffLen);
54
55 mfcTagCmdBuff[2] = mfcTagCmdBuffLen;
56 mfcDataLen = mfcTagCmdBuffLen + NCI_HEADER_SIZE;
57 int writtenDataLen = phNxpNciHal_write_internal(mfcDataLen, mfcTagCmdBuff);
58
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) {
62 SendIncDecRestoreCmdPart2(pMfcData);
63 }
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 *******************************************************************************/
BuildMfcCmd(uint8_t * pData,uint16_t * pLength)76 void NxpMfcReader::BuildMfcCmd(uint8_t* pData, uint16_t* pLength) {
77 uint16_t cmdBuffLen = *pLength;
78 memcpy(mMfcTagCmdIntfData.sendBuf, pData, cmdBuffLen);
79 mMfcTagCmdIntfData.sendBufLen = cmdBuffLen;
80
81 switch (pData[0]) {
82 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;
100 }
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 *******************************************************************************/
BuildAuthCmd()116 void 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;
137 memmove(&mMfcTagCmdIntfData.sendBuf[3], &mMfcTagCmdIntfData.sendBuf[6],
138 MFC_AUTHKEYLEN);
139 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 *******************************************************************************/
CalcSectorAddress()157 void 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 *******************************************************************************/
BuildReadCmd()179 void 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 *******************************************************************************/
BuildWrite16Cmd()190 void 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 *******************************************************************************/
BuildRawCmd()206 void 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 *******************************************************************************/
BuildIncDecCmd()222 void NxpMfcReader::BuildIncDecCmd() {
223 mMfcTagCmdIntfData.sendBufLen = 0x03; // eMfRawDataXchgHdr + cmd +
224 // blockaddress
225 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 *******************************************************************************/
AuthForWrite()239 void 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 *******************************************************************************/
SendIncDecRestoreCmdPart2(const uint8_t * mfcData)266 void NxpMfcReader::SendIncDecRestoreCmdPart2(const uint8_t* mfcData) {
267 NFCSTATUS status = NFCSTATUS_SUCCESS;
268 /* Build TAG_CMD part 2 for Mifare increment ,decrement and restore commands*/
269 uint8_t incDecRestorePart2[] = {0x00, 0x00, 0x05, (uint8_t)eMfRawDataXchgHdr,
270 0x00, 0x00, 0x00, 0x00};
271 uint8_t incDecRestorePart2Size =
272 (sizeof(incDecRestorePart2) / sizeof(incDecRestorePart2[0]));
273 if (mfcData[3] == eMifareInc || mfcData[3] == eMifareDec) {
274 for (int i = 4; i < incDecRestorePart2Size; i++) {
275 incDecRestorePart2[i] = mfcData[i + 1];
276 }
277 }
278 sendRspToUpperLayer = false;
279 status = phNxpNciHal_send_ext_cmd(incDecRestorePart2Size, incDecRestorePart2);
280 if (status != NFCSTATUS_SUCCESS) {
281 NXPLOG_NCIHAL_E("Mifare Cmd for inc/dec/Restore part 2 failed");
282 }
283 return;
284 }
285
286 /*******************************************************************************
287 **
288 ** Function AnalyzeMfcResp
289 **
290 ** Description Analyze type of MFC response and build MFC response from
291 ** Tag cmd Intf response?
292 **
293 ** Returns NFCSTATUS_SUCCESS - Data Reception is successful
294 ** NFCSTATUS_FAILED - Data Reception failed
295 **
296 *******************************************************************************/
AnalyzeMfcResp(uint8_t * pBuff,uint16_t * pBufflen)297 NFCSTATUS NxpMfcReader::AnalyzeMfcResp(uint8_t* pBuff, uint16_t* pBufflen) {
298 NFCSTATUS status = NFCSTATUS_SUCCESS;
299 uint16_t wPldDataSize = 0;
300 MfcRespId_t RecvdExtnRspId = eInvalidRsp;
301
302 if (0 == (*pBufflen)) {
303 status = NFCSTATUS_FAILED;
304 } else {
305 RecvdExtnRspId = (MfcRespId_t)pBuff[0];
306 NXPLOG_NCIHAL_E("%s: RecvdExtnRspId=%d", __func__, RecvdExtnRspId);
307 switch (RecvdExtnRspId) {
308 case eMfXchgDataRsp: {
309 NFCSTATUS writeRespStatus = NFCSTATUS_SUCCESS;
310 /* check the status byte */
311 if (*pBufflen == 3) {
312 if ((pBuff[0] == 0x10) && (pBuff[1] != 0x0A)) {
313 NXPLOG_NCIHAL_E("Mifare Error in payload response");
314 *pBufflen = 0x1;
315 pBuff[0] = NFCSTATUS_FAILED;
316 return NFCSTATUS_FAILED;
317 } else {
318 pBuff[0] = NFCSTATUS_SUCCESS;
319 return NFCSTATUS_SUCCESS;
320 }
321 }
322 writeRespStatus = pBuff[*pBufflen - 1];
323
324 if (NFCSTATUS_SUCCESS == writeRespStatus) {
325 status = NFCSTATUS_SUCCESS;
326 uint16_t wRecvDataSz = 0;
327
328 wPldDataSize =
329 ((*pBufflen) - (MFC_EXTN_ID_SIZE + MFC_EXTN_STATUS_SIZE));
330 wRecvDataSz = MAX_MFC_BUFF_SIZE;
331 if ((wPldDataSize) <= wRecvDataSz) {
332 /* Extract the data part from pBuff[2] & fill it to be sent to
333 * upper layer */
334 memmove(&(pBuff[0]), &(pBuff[1]), wPldDataSize);
335 /* update the number of bytes received from lower layer,excluding
336 * the status byte */
337 *pBufflen = wPldDataSize;
338 } else {
339 status = NFCSTATUS_FAILED;
340 }
341 } else {
342 status = NFCSTATUS_FAILED;
343 }
344 } break;
345
346 case eMfcAuthRsp: {
347 /* check the status byte */
348 if (NFCSTATUS_SUCCESS == pBuff[1]) {
349 status = NFCSTATUS_SUCCESS;
350 /* DataLen = TotalRecvdLen - (sizeof(RspId) + sizeof(Status)) */
351 wPldDataSize =
352 ((*pBufflen) - (MFC_EXTN_ID_SIZE + MFC_EXTN_STATUS_SIZE));
353 /* Extract the data part from pBuff[2] & fill it to be sent to upper
354 * layer */
355 pBuff[0] = pBuff[1];
356 /* update the number of bytes received from lower layer,excluding
357 * the status byte */
358 *pBufflen = wPldDataSize + 1;
359 } else {
360 pBuff[0] = pBuff[1];
361 *pBufflen = 1;
362 status = NFCSTATUS_FAILED;
363 }
364 } break;
365 default: {
366 status = NFCSTATUS_FAILED;
367 } break;
368 }
369 }
370 return status;
371 }
372
373 /*******************************************************************************
374 **
375 ** Function CheckMfcResponse
376 **
377 ** Description This function is called to check if it's a valid Mfc
378 ** response data
379 **
380 ** Returns NFCSTATUS_SUCCESS
381 ** NFCSTATUS_FAILED
382 **
383 *******************************************************************************/
CheckMfcResponse(uint8_t * pTransceiveData,uint16_t transceiveDataLen)384 NFCSTATUS NxpMfcReader::CheckMfcResponse(uint8_t* pTransceiveData,
385 uint16_t transceiveDataLen) {
386 NFCSTATUS status = NFCSTATUS_SUCCESS;
387
388 if (transceiveDataLen == 3) {
389 if ((pTransceiveData)[0] == 0x10 && (pTransceiveData)[1] != 0x0A) {
390 NXPLOG_NCIHAL_E("Mifare Error in payload response");
391 transceiveDataLen = 0x1;
392 pTransceiveData += 1;
393 return NFCSTATUS_FAILED;
394 }
395 }
396 if ((pTransceiveData)[0] == 0x40) {
397 pTransceiveData += 1;
398 transceiveDataLen = 0x01;
399 if ((pTransceiveData)[0] == 0x03) {
400 transceiveDataLen = 0x00;
401 status = NFCSTATUS_FAILED;
402 }
403 } else if ((pTransceiveData)[0] == 0x10) {
404 pTransceiveData += 1;
405 transceiveDataLen = 0x10;
406 }
407 return status;
408 }
409