1 /*
2 * Copyright (C) 2012-2019 NXP Semiconductors
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <log/log.h>
17 #include <phDal4Nfc_messageQueueLib.h>
18 #include <phNxpConfig.h>
19 #include <phNxpLog.h>
20 #include <phNxpNciHal.h>
21 #include <phNxpNciHal_Adaptation.h>
22 #include "hal_nxpnfc.h"
23 #include "hal_nxpese.h"
24 #include <phNxpNciHal_NfcDepSWPrio.h>
25 #include <phNxpNciHal_ext.h>
26 #include <phTmlNfc.h>
27 /* Timeout value to wait for response from PN548AD */
28 #define HAL_EXTNS_WRITE_RSP_TIMEOUT (1000)
29
30 #undef P2P_PRIO_LOGIC_HAL_IMP
31
32 /******************* Global variables *****************************************/
33 extern phNxpNciHal_Control_t nxpncihal_ctrl;
34 extern phNxpNciProfile_Control_t nxpprofile_ctrl;
35 extern uint32_t cleanup_timer;
36 extern bool nfc_debug_enabled;
37 uint8_t icode_detected = 0x00;
38 uint8_t icode_send_eof = 0x00;
39 static uint8_t ee_disc_done = 0x00;
40 uint8_t EnableP2P_PrioLogic = false;
41 extern bool bEnableMfcExtns;
42 extern bool bEnableMfcReader;
43 extern bool bDisableLegacyMfcExtns;
44 static uint32_t RfDiscID = 1;
45 static uint32_t RfProtocolType = 4;
46 /* NFCEE Set mode */
47 static uint8_t setEEModeDone = 0x00;
48 /* External global variable to get FW version from NCI response*/
49 extern uint32_t wFwVerRsp;
50 /* External global variable to get FW version from FW file*/
51 extern uint16_t wFwVer;
52
53 uint16_t fw_maj_ver;
54 uint16_t rom_version;
55
56 extern uint32_t timeoutTimerId;
57
58 /************** HAL extension functions ***************************************/
59 static void hal_extns_write_rsp_timeout_cb(uint32_t TimerId, void* pContext);
60
61 /*Proprietary cmd sent to HAL to send reader mode flag
62 * Last byte of 4 byte proprietary cmd data contains ReaderMode flag
63 * If this flag is enabled, NFC-DEP protocol is modified to T3T protocol
64 * if FrameRF interface is selected. This needs to be done as the FW
65 * always sends Ntf for FrameRF with NFC-DEP even though FrameRF with T3T is
66 * previously selected with DISCOVER_SELECT_CMD
67 */
68 #define PROPRIETARY_CMD_FELICA_READER_MODE 0xFE
69 static uint8_t gFelicaReaderMode;
70
71 static NFCSTATUS phNxpNciHal_ext_process_nfc_init_rsp(uint8_t* p_ntf,
72 uint16_t* p_len);
73 /*******************************************************************************
74 **
75 ** Function phNxpNciHal_ext_init
76 **
77 ** Description initialize extension function
78 **
79 *******************************************************************************/
phNxpNciHal_ext_init(void)80 void phNxpNciHal_ext_init(void) {
81 icode_detected = 0x00;
82 icode_send_eof = 0x00;
83 setEEModeDone = 0x00;
84 EnableP2P_PrioLogic = false;
85 }
86
87 /*******************************************************************************
88 **
89 ** Function phNxpNciHal_process_ext_rsp
90 **
91 ** Description Process extension function response
92 **
93 ** Returns NFCSTATUS_SUCCESS if success
94 **
95 *******************************************************************************/
phNxpNciHal_process_ext_rsp(uint8_t * p_ntf,uint16_t * p_len)96 NFCSTATUS phNxpNciHal_process_ext_rsp(uint8_t* p_ntf, uint16_t* p_len) {
97 NFCSTATUS status = NFCSTATUS_SUCCESS;
98
99 if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && *p_len < 14) {
100 if(*p_len <= 6) {
101 android_errorWriteLog(0x534e4554, "118152591");
102 }
103 NXPLOG_NCIHAL_E("RF_INTF_ACTIVATED_NTF length error!");
104 status = NFCSTATUS_FAILED;
105 return status;
106 }
107
108 if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x03 &&
109 p_ntf[5] == 0x05 && nxpprofile_ctrl.profile_type == EMV_CO_PROFILE) {
110 p_ntf[4] = 0xFF;
111 p_ntf[5] = 0xFF;
112 p_ntf[6] = 0xFF;
113 NXPLOG_NCIHAL_D("Nfc-Dep Detect in EmvCo profile - Restart polling");
114 }
115
116 if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x01 &&
117 p_ntf[5] == 0x05 && p_ntf[6] == 0x02 && gFelicaReaderMode) {
118 /*If FelicaReaderMode is enabled,Change Protocol to T3T from NFC-DEP
119 * when FrameRF interface is selected*/
120 p_ntf[5] = 0x03;
121 NXPLOG_NCIHAL_D("FelicaReaderMode:Activity 1.1");
122 }
123
124 #ifdef P2P_PRIO_LOGIC_HAL_IMP
125 if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x02 &&
126 p_ntf[5] == 0x04 && nxpprofile_ctrl.profile_type == NFC_FORUM_PROFILE) {
127 EnableP2P_PrioLogic = true;
128 }
129
130 NXPLOG_NCIHAL_D("Is EnableP2P_PrioLogic: 0x0%X", EnableP2P_PrioLogic);
131 if (phNxpDta_IsEnable() == false) {
132 if ((icode_detected != 1) && (EnableP2P_PrioLogic == true)) {
133 if (phNxpNciHal_NfcDep_comapre_ntf(p_ntf, *p_len) == NFCSTATUS_FAILED) {
134 status = phNxpNciHal_NfcDep_rsp_ext(p_ntf, p_len);
135 if (status != NFCSTATUS_INVALID_PARAMETER) {
136 return status;
137 }
138 }
139 }
140 }
141 #endif
142
143 status = NFCSTATUS_SUCCESS;
144
145 if (bDisableLegacyMfcExtns && bEnableMfcExtns && p_ntf[0] == 0) {
146 uint16_t extlen;
147 extlen = *p_len - NCI_HEADER_SIZE;
148 NxpMfcReaderInstance.AnalyzeMfcResp(&p_ntf[3], &extlen);
149 p_ntf[2] = extlen;
150 *p_len = extlen + NCI_HEADER_SIZE;
151 }
152
153 if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05) {
154 bEnableMfcExtns = false;
155 if (bDisableLegacyMfcExtns && p_ntf[4] == 0x80 && p_ntf[5] == 0x80) {
156 bEnableMfcExtns = true;
157 NXPLOG_NCIHAL_D("NxpNci: RF Interface = Mifare Enable MifareExtns");
158 }
159 switch (p_ntf[4]) {
160 case 0x00:
161 NXPLOG_NCIHAL_D("NxpNci: RF Interface = NFCEE Direct RF");
162 break;
163 case 0x01:
164 NXPLOG_NCIHAL_D("NxpNci: RF Interface = Frame RF");
165 break;
166 case 0x02:
167 NXPLOG_NCIHAL_D("NxpNci: RF Interface = ISO-DEP");
168 break;
169 case 0x03:
170 NXPLOG_NCIHAL_D("NxpNci: RF Interface = NFC-DEP");
171 break;
172 case 0x80:
173 NXPLOG_NCIHAL_D("NxpNci: RF Interface = MIFARE");
174 break;
175 default:
176 NXPLOG_NCIHAL_D("NxpNci: RF Interface = Unknown");
177 break;
178 }
179
180 switch (p_ntf[5]) {
181 case 0x01:
182 NXPLOG_NCIHAL_D("NxpNci: Protocol = T1T");
183 phNxpDta_T1TEnable();
184 break;
185 case 0x02:
186 NXPLOG_NCIHAL_D("NxpNci: Protocol = T2T");
187 break;
188 case 0x03:
189 NXPLOG_NCIHAL_D("NxpNci: Protocol = T3T");
190 break;
191 case 0x04:
192 NXPLOG_NCIHAL_D("NxpNci: Protocol = ISO-DEP");
193 break;
194 case 0x05:
195 NXPLOG_NCIHAL_D("NxpNci: Protocol = NFC-DEP");
196 break;
197 case 0x06:
198 NXPLOG_NCIHAL_D("NxpNci: Protocol = 15693");
199 break;
200 case 0x80:
201 NXPLOG_NCIHAL_D("NxpNci: Protocol = MIFARE");
202 break;
203 case 0x81:
204 NXPLOG_NCIHAL_D("NxpNci: Protocol = Kovio");
205 break;
206 default:
207 NXPLOG_NCIHAL_D("NxpNci: Protocol = Unknown");
208 break;
209 }
210
211 switch (p_ntf[6]) {
212 case 0x00:
213 NXPLOG_NCIHAL_D("NxpNci: Mode = A Passive Poll");
214 break;
215 case 0x01:
216 NXPLOG_NCIHAL_D("NxpNci: Mode = B Passive Poll");
217 break;
218 case 0x02:
219 NXPLOG_NCIHAL_D("NxpNci: Mode = F Passive Poll");
220 break;
221 case 0x03:
222 NXPLOG_NCIHAL_D("NxpNci: Mode = A Active Poll");
223 break;
224 case 0x05:
225 NXPLOG_NCIHAL_D("NxpNci: Mode = F Active Poll");
226 break;
227 case 0x06:
228 NXPLOG_NCIHAL_D("NxpNci: Mode = 15693 Passive Poll");
229 break;
230 case 0x70:
231 NXPLOG_NCIHAL_D("NxpNci: Mode = Kovio");
232 break;
233 case 0x80:
234 NXPLOG_NCIHAL_D("NxpNci: Mode = A Passive Listen");
235 break;
236 case 0x81:
237 NXPLOG_NCIHAL_D("NxpNci: Mode = B Passive Listen");
238 break;
239 case 0x82:
240 NXPLOG_NCIHAL_D("NxpNci: Mode = F Passive Listen");
241 break;
242 case 0x83:
243 NXPLOG_NCIHAL_D("NxpNci: Mode = A Active Listen");
244 break;
245 case 0x85:
246 NXPLOG_NCIHAL_D("NxpNci: Mode = F Active Listen");
247 break;
248 case 0x86:
249 NXPLOG_NCIHAL_D("NxpNci: Mode = 15693 Passive Listen");
250 break;
251 default:
252 NXPLOG_NCIHAL_D("NxpNci: Mode = Unknown");
253 break;
254 }
255 }
256 phNxpNciHal_ext_process_nfc_init_rsp(p_ntf, p_len);
257
258 if (p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[2] == 0x15 &&
259 p_ntf[4] == 0x01 && p_ntf[5] == 0x06 && p_ntf[6] == 0x06) {
260 NXPLOG_NCIHAL_D("> Going through workaround - notification of ISO 15693");
261 icode_detected = 0x01;
262 p_ntf[21] = 0x01;
263 p_ntf[22] = 0x01;
264 } else if (icode_detected == 1 && icode_send_eof == 2) {
265 icode_send_eof = 3;
266 } else if (p_ntf[0] == 0x00 && p_ntf[1] == 0x00 && icode_detected == 1) {
267 if (icode_send_eof == 3) {
268 icode_send_eof = 0;
269 }
270 if (nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0) {
271 if (p_ntf[p_ntf[2] + 2] == 0x00) {
272 NXPLOG_NCIHAL_D("> Going through workaround - data of ISO 15693");
273 p_ntf[2]--;
274 (*p_len)--;
275 } else {
276 p_ntf[p_ntf[2] + 2] |= 0x01;
277 }
278 }
279 } else if (p_ntf[2] == 0x02 && p_ntf[1] == 0x00 && icode_detected == 1) {
280 NXPLOG_NCIHAL_D("> ICODE EOF response do not send to upper layer");
281 } else if (p_ntf[0] == 0x61 && p_ntf[1] == 0x06 && icode_detected == 1) {
282 NXPLOG_NCIHAL_D("> Polling Loop Re-Started");
283 icode_detected = 0;
284 icode_send_eof = 0;
285 } else if (*p_len == 4 && p_ntf[0] == 0x40 && p_ntf[1] == 0x02 &&
286 p_ntf[2] == 0x01 && p_ntf[3] == 0x06) {
287 NXPLOG_NCIHAL_D("> Deinit workaround for LLCP set_config 0x%x 0x%x 0x%x",
288 p_ntf[21], p_ntf[22], p_ntf[23]);
289 p_ntf[0] = 0x40;
290 p_ntf[1] = 0x02;
291 p_ntf[2] = 0x02;
292 p_ntf[3] = 0x00;
293 p_ntf[4] = 0x00;
294 *p_len = 5;
295 }
296 // 4200 02 00 01
297 else if (p_ntf[0] == 0x42 && p_ntf[1] == 0x00 && ee_disc_done == 0x01) {
298 NXPLOG_NCIHAL_D("Going through workaround - NFCEE_DISCOVER_RSP");
299 if (p_ntf[4] == 0x01) {
300 p_ntf[4] = 0x00;
301
302 ee_disc_done = 0x00;
303 }
304 NXPLOG_NCIHAL_D("Going through workaround - NFCEE_DISCOVER_RSP - END");
305
306 } else if (p_ntf[0] == 0x61 && p_ntf[1] == 0x03 /*&& cleanup_timer!=0*/) {
307 if (cleanup_timer != 0) {
308 /* if RF Notification Type of RF_DISCOVER_NTF is Last Notification */
309 if (0 == (*(p_ntf + 2 + (*(p_ntf + 2))))) {
310 phNxpNciHal_select_RF_Discovery(RfDiscID, RfProtocolType);
311 status = NFCSTATUS_FAILED;
312 return status;
313 } else {
314 RfDiscID = p_ntf[3];
315 RfProtocolType = p_ntf[4];
316 }
317 status = NFCSTATUS_FAILED;
318 return status;
319 }
320 } else if (p_ntf[0] == 0x41 && p_ntf[1] == 0x04 && cleanup_timer != 0) {
321 status = NFCSTATUS_FAILED;
322 return status;
323 }
324 else if (*p_len == 4 && p_ntf[0] == 0x4F && p_ntf[1] == 0x11 &&
325 p_ntf[2] == 0x01) {
326 if (p_ntf[3] == 0x00) {
327 NXPLOG_NCIHAL_D(
328 "> Workaround for ISO-DEP Presence Check, ignore response and wait "
329 "for notification");
330 p_ntf[0] = 0x60;
331 p_ntf[1] = 0x06;
332 p_ntf[2] = 0x03;
333 p_ntf[3] = 0x01;
334 p_ntf[4] = 0x00;
335 p_ntf[5] = 0x01;
336 *p_len = 6;
337 } else {
338 NXPLOG_NCIHAL_D(
339 "> Workaround for ISO-DEP Presence Check, presence check return "
340 "failed");
341 p_ntf[0] = 0x60;
342 p_ntf[1] = 0x08;
343 p_ntf[2] = 0x02;
344 p_ntf[3] = 0xB2;
345 p_ntf[4] = 0x00;
346 *p_len = 5;
347 }
348 } else if (*p_len == 4 && p_ntf[0] == 0x6F && p_ntf[1] == 0x11 &&
349 p_ntf[2] == 0x01) {
350 if (p_ntf[3] == 0x01) {
351 NXPLOG_NCIHAL_D(
352 "> Workaround for ISO-DEP Presence Check - Card still in field");
353 p_ntf[0] = 0x00;
354 p_ntf[1] = 0x00;
355 p_ntf[2] = 0x01;
356 p_ntf[3] = 0x7E;
357 } else {
358 NXPLOG_NCIHAL_D(
359 "> Workaround for ISO-DEP Presence Check - Card not in field");
360 p_ntf[0] = 0x60;
361 p_ntf[1] = 0x08;
362 p_ntf[2] = 0x02;
363 p_ntf[3] = 0xB2;
364 p_ntf[4] = 0x00;
365 *p_len = 5;
366 }
367 }
368
369
370 if (*p_len == 4 && p_ntf[0] == 0x61 && p_ntf[1] == 0x07 ) {
371 unsigned long rf_update_enable = 0;
372 if(GetNxpNumValue(NAME_RF_STATUS_UPDATE_ENABLE, &rf_update_enable, sizeof(unsigned long))) {
373 NXPLOG_NCIHAL_D(
374 "RF_STATUS_UPDATE_ENABLE : %lu",rf_update_enable);
375 }
376 if(rf_update_enable == 0x01) {
377 nfc_nci_IoctlInOutData_t inpOutData;
378 uint8_t rf_state_update[] = {0x00};
379 memset(&inpOutData, 0x00, sizeof(nfc_nci_IoctlInOutData_t));
380 inpOutData.inp.data.nciCmd.cmd_len = sizeof(rf_state_update);
381 rf_state_update[0]=p_ntf[3];
382 memcpy(inpOutData.inp.data.nciCmd.p_cmd, rf_state_update,sizeof(rf_state_update));
383 inpOutData.inp.data_source = 2;
384 phNxpNciHal_ioctl(HAL_NFC_IOCTL_RF_STATUS_UPDATE, &inpOutData);
385 }
386 }
387 /*
388 else if(p_ntf[0] == 0x61 && p_ntf[1] == 0x05 && p_ntf[4] == 0x01 && p_ntf[5]
389 == 0x00 && p_ntf[6] == 0x01)
390 {
391 NXPLOG_NCIHAL_D("Picopass type 3-B with undefined protocol is not
392 supported, disabling");
393 p_ntf[4] = 0xFF;
394 p_ntf[5] = 0xFF;
395 p_ntf[6] = 0xFF;
396 }*/
397
398 return status;
399 }
400
401 /******************************************************************************
402 * Function phNxpNciHal_ext_process_nfc_init_rsp
403 *
404 * Description This function is used to process the HAL NFC core reset rsp
405 * and ntf and core init rsp of NCI 1.0 or NCI2.0 and update
406 * NCI version.
407 * It also handles error response such as core_reset_ntf with
408 * error status in both NCI2.0 and NCI1.0.
409 *
410 * Returns Returns NFCSTATUS_SUCCESS if parsing response is successful
411 * or returns failure.
412 *
413 *******************************************************************************/
phNxpNciHal_ext_process_nfc_init_rsp(uint8_t * p_ntf,uint16_t * p_len)414 static NFCSTATUS phNxpNciHal_ext_process_nfc_init_rsp(uint8_t* p_ntf,
415 uint16_t* p_len) {
416 NFCSTATUS status = NFCSTATUS_SUCCESS;
417
418 /* Parsing CORE_RESET_RSP and CORE_RESET_NTF to update NCI version.*/
419 if (p_ntf == NULL || *p_len == 0x00) {
420 return NFCSTATUS_FAILED;
421 }
422 if (p_ntf[0] == NCI_MT_RSP &&
423 ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_RESET)) {
424 if (p_ntf[2] == 0x01 && p_ntf[3] == 0x00) {
425 NXPLOG_NCIHAL_D("CORE_RESET_RSP NCI2.0");
426 if (nxpncihal_ctrl.hal_ext_enabled == TRUE) {
427 nxpncihal_ctrl.nci_info.wait_for_ntf = TRUE;
428 }
429 } else if (p_ntf[2] == 0x03 && p_ntf[3] == 0x00) {
430 NXPLOG_NCIHAL_D("CORE_RESET_RSP NCI1.0");
431 nxpncihal_ctrl.nci_info.nci_version = p_ntf[4];
432 }
433 } else if (p_ntf[0] == NCI_MT_NTF &&
434 ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_RESET)) {
435 if (p_ntf[3] == CORE_RESET_TRIGGER_TYPE_CORE_RESET_CMD_RECEIVED ||
436 p_ntf[3] == CORE_RESET_TRIGGER_TYPE_POWERED_ON) {
437 NXPLOG_NCIHAL_D("CORE_RESET_NTF NCI2.0 reason CORE_RESET_CMD received !");
438 nxpncihal_ctrl.nci_info.nci_version = p_ntf[5];
439 NXPLOG_NCIHAL_D("nci_version : 0x%02x",nxpncihal_ctrl.nci_info.nci_version);
440 if(!nxpncihal_ctrl.hal_open_status) {
441 phNxpNciHal_configFeatureList(p_ntf,*p_len);
442 }
443 int len = p_ntf[2] + 2; /*include 2 byte header*/
444 if(len != *p_len - 1) {
445 NXPLOG_NCIHAL_E("phNxpNciHal_ext_process_nfc_init_rsp invalid NTF length");
446 android_errorWriteLog(0x534e4554, "121263487");
447 return NFCSTATUS_FAILED;
448 }
449 wFwVerRsp = (((uint32_t)p_ntf[len - 2]) << 16U) |
450 (((uint32_t)p_ntf[len - 1]) << 8U) | p_ntf[len];
451 NXPLOG_NCIHAL_D("NxpNci> FW Version: %x.%x.%x", p_ntf[len - 2],
452 p_ntf[len - 1], p_ntf[len]);
453 fw_maj_ver = p_ntf[len - 1];
454 rom_version = p_ntf[len - 2];
455 } else {
456 uint32_t i;
457 char print_buffer[*p_len * 3 + 1];
458
459 memset(print_buffer, 0, sizeof(print_buffer));
460 for (i = 0; i < *p_len; i++) {
461 snprintf(&print_buffer[i * 2], 3, "%02X", p_ntf[i]);
462 }
463 NXPLOG_NCIHAL_D("CORE_RESET_NTF received !");
464 NXPLOG_NCIR_E("len = %3d > %s", *p_len, print_buffer);
465 phNxpNciHal_emergency_recovery();
466 status = NFCSTATUS_FAILED;
467 } /* Parsing CORE_INIT_RSP*/
468 } else if (p_ntf[0] == NCI_MT_RSP &&
469 ((p_ntf[1] & NCI_OID_MASK) == NCI_MSG_CORE_INIT)) {
470 if (nxpncihal_ctrl.nci_info.nci_version == NCI_VERSION_2_0) {
471 NXPLOG_NCIHAL_D("CORE_INIT_RSP NCI2.0 received !");
472 } else {
473 NXPLOG_NCIHAL_D("CORE_INIT_RSP NCI1.0 received !");
474 if(!nxpncihal_ctrl.hal_open_status) {
475 phNxpNciHal_configFeatureList(p_ntf,*p_len);
476 }
477 int len = p_ntf[2] + 2; /*include 2 byte header*/
478 if(len != *p_len - 1) {
479 NXPLOG_NCIHAL_E("phNxpNciHal_ext_process_nfc_init_rsp invalid NTF length");
480 android_errorWriteLog(0x534e4554, "121263487");
481 return NFCSTATUS_FAILED;
482 }
483 wFwVerRsp = (((uint32_t)p_ntf[len - 2]) << 16U) |
484 (((uint32_t)p_ntf[len - 1]) << 8U) | p_ntf[len];
485 if (wFwVerRsp == 0) status = NFCSTATUS_FAILED;
486 NXPLOG_NCIHAL_D("NxpNci> FW Version: %x.%x.%x", p_ntf[len - 2],
487 p_ntf[len - 1], p_ntf[len]);
488 fw_maj_ver = p_ntf[len - 1];
489 rom_version = p_ntf[len - 2];
490 }
491 }
492 return status;
493 }
494
495 /******************************************************************************
496 * Function phNxpNciHal_process_ext_cmd_rsp
497 *
498 * Description This function process the extension command response. It
499 * also checks the received response to expected response.
500 *
501 * Returns returns NFCSTATUS_SUCCESS if response is as expected else
502 * returns failure.
503 *
504 ******************************************************************************/
phNxpNciHal_process_ext_cmd_rsp(uint16_t cmd_len,uint8_t * p_cmd)505 static NFCSTATUS phNxpNciHal_process_ext_cmd_rsp(uint16_t cmd_len,
506 uint8_t* p_cmd) {
507 NFCSTATUS status = NFCSTATUS_FAILED;
508 uint16_t data_written = 0;
509
510 /* Create the local semaphore */
511 if (phNxpNciHal_init_cb_data(&nxpncihal_ctrl.ext_cb_data, NULL) !=
512 NFCSTATUS_SUCCESS) {
513 NXPLOG_NCIHAL_D("Create ext_cb_data failed");
514 return NFCSTATUS_FAILED;
515 }
516
517 nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_SUCCESS;
518
519 /* Send ext command */
520 data_written = phNxpNciHal_write_unlocked(cmd_len, p_cmd);
521 if (data_written != cmd_len) {
522 NXPLOG_NCIHAL_D("phNxpNciHal_write failed for hal ext");
523 goto clean_and_return;
524 }
525
526 /* Start timer */
527 status = phOsalNfc_Timer_Start(timeoutTimerId, HAL_EXTNS_WRITE_RSP_TIMEOUT,
528 &hal_extns_write_rsp_timeout_cb, NULL);
529 if (NFCSTATUS_SUCCESS == status) {
530 NXPLOG_NCIHAL_D("Response timer started");
531 } else {
532 NXPLOG_NCIHAL_E("Response timer not started!!!");
533 status = NFCSTATUS_FAILED;
534 goto clean_and_return;
535 }
536
537 /* Wait for rsp */
538 NXPLOG_NCIHAL_D("Waiting after ext cmd sent");
539 if (SEM_WAIT(nxpncihal_ctrl.ext_cb_data)) {
540 NXPLOG_NCIHAL_E("p_hal_ext->ext_cb_data.sem semaphore error");
541 goto clean_and_return;
542 }
543
544 /* Stop Timer */
545 status = phOsalNfc_Timer_Stop(timeoutTimerId);
546 if (NFCSTATUS_SUCCESS == status) {
547 NXPLOG_NCIHAL_D("Response timer stopped");
548 } else {
549 NXPLOG_NCIHAL_E("Response timer stop ERROR!!!");
550 status = NFCSTATUS_FAILED;
551 goto clean_and_return;
552 }
553 /* No NTF expected for OMAPI command */
554 if(p_cmd[0] == 0x2F && p_cmd[1] == 0x1 && p_cmd[2] == 0x01) {
555 nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE;
556 }
557 /* Start timer to wait for NTF*/
558 if (nxpncihal_ctrl.nci_info.wait_for_ntf == TRUE) {
559 status = phOsalNfc_Timer_Start(timeoutTimerId, HAL_EXTNS_WRITE_RSP_TIMEOUT,
560 &hal_extns_write_rsp_timeout_cb, NULL);
561 if (NFCSTATUS_SUCCESS == status) {
562 NXPLOG_NCIHAL_D("Response timer started");
563 } else {
564 NXPLOG_NCIHAL_E("Response timer not started!!!");
565 status = NFCSTATUS_FAILED;
566 goto clean_and_return;
567 }
568 if (SEM_WAIT(nxpncihal_ctrl.ext_cb_data)) {
569 NXPLOG_NCIHAL_E("p_hal_ext->ext_cb_data.sem semaphore error");
570 /* Stop Timer */
571 status = phOsalNfc_Timer_Stop(timeoutTimerId);
572 goto clean_and_return;
573 }
574 status = phOsalNfc_Timer_Stop(timeoutTimerId);
575 if (NFCSTATUS_SUCCESS == status) {
576 NXPLOG_NCIHAL_D("Response timer stopped");
577 } else {
578 NXPLOG_NCIHAL_E("Response timer stop ERROR!!!");
579 status = NFCSTATUS_FAILED;
580 goto clean_and_return;
581 }
582 }
583
584 if (nxpncihal_ctrl.ext_cb_data.status != NFCSTATUS_SUCCESS && p_cmd[0] != 0x2F && p_cmd[1] != 0x1 && p_cmd[2] == 0x01) {
585 NXPLOG_NCIHAL_E(
586 "Callback Status is failed!! Timer Expired!! Couldn't read it! 0x%x",
587 nxpncihal_ctrl.ext_cb_data.status);
588 status = NFCSTATUS_FAILED;
589 goto clean_and_return;
590 }
591
592 NXPLOG_NCIHAL_D("Checking response");
593 status = NFCSTATUS_SUCCESS;
594
595 clean_and_return:
596 phNxpNciHal_cleanup_cb_data(&nxpncihal_ctrl.ext_cb_data);
597 nxpncihal_ctrl.nci_info.wait_for_ntf = FALSE;
598 return status;
599 }
600
601 /******************************************************************************
602 * Function phNxpNciHal_write_ext
603 *
604 * Description This function inform the status of phNxpNciHal_open
605 * function to libnfc-nci.
606 *
607 * Returns It return NFCSTATUS_SUCCESS then continue with send else
608 * sends NFCSTATUS_FAILED direct response is prepared and
609 * do not send anything to NFCC.
610 *
611 ******************************************************************************/
612
phNxpNciHal_write_ext(uint16_t * cmd_len,uint8_t * p_cmd_data,uint16_t * rsp_len,uint8_t * p_rsp_data)613 NFCSTATUS phNxpNciHal_write_ext(uint16_t* cmd_len, uint8_t* p_cmd_data,
614 uint16_t* rsp_len, uint8_t* p_rsp_data) {
615 NFCSTATUS status = NFCSTATUS_SUCCESS;
616
617 phNxpNciHal_NfcDep_cmd_ext(p_cmd_data, cmd_len);
618
619 if (phNxpDta_IsEnable() == true) {
620 status = phNxpNHal_DtaUpdate(cmd_len, p_cmd_data, rsp_len, p_rsp_data);
621 }
622
623 if (p_cmd_data[0] == PROPRIETARY_CMD_FELICA_READER_MODE &&
624 p_cmd_data[1] == PROPRIETARY_CMD_FELICA_READER_MODE &&
625 p_cmd_data[2] == PROPRIETARY_CMD_FELICA_READER_MODE) {
626 NXPLOG_NCIHAL_D("Received proprietary command to set Felica Reader mode:%d",
627 p_cmd_data[3]);
628 gFelicaReaderMode = p_cmd_data[3];
629 /* frame the dummy response */
630 *rsp_len = 4;
631 p_rsp_data[0] = 0x00;
632 p_rsp_data[1] = 0x00;
633 p_rsp_data[2] = 0x00;
634 p_rsp_data[3] = 0x00;
635 status = NFCSTATUS_FAILED;
636 } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 &&
637 p_cmd_data[2] == 0x05 && p_cmd_data[3] == 0x01 &&
638 p_cmd_data[4] == 0xA0 && p_cmd_data[5] == 0x44 &&
639 p_cmd_data[6] == 0x01 && p_cmd_data[7] == 0x01) {
640 nxpprofile_ctrl.profile_type = EMV_CO_PROFILE;
641 NXPLOG_NCIHAL_D("EMV_CO_PROFILE mode - Enabled");
642 status = NFCSTATUS_SUCCESS;
643 } else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 &&
644 p_cmd_data[2] == 0x05 && p_cmd_data[3] == 0x01 &&
645 p_cmd_data[4] == 0xA0 && p_cmd_data[5] == 0x44 &&
646 p_cmd_data[6] == 0x01 && p_cmd_data[7] == 0x00) {
647 NXPLOG_NCIHAL_D("NFC_FORUM_PROFILE mode - Enabled");
648 nxpprofile_ctrl.profile_type = NFC_FORUM_PROFILE;
649 status = NFCSTATUS_SUCCESS;
650 }
651
652 if (nxpprofile_ctrl.profile_type == EMV_CO_PROFILE) {
653 if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x06 &&
654 p_cmd_data[2] == 0x01 && p_cmd_data[3] == 0x03) {
655 #if 0
656 //Needs clarification whether to keep it or not
657 NXPLOG_NCIHAL_D ("EmvCo Poll mode - RF Deactivate discard");
658 phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
659 *rsp_len = 4;
660 p_rsp_data[0] = 0x41;
661 p_rsp_data[1] = 0x06;
662 p_rsp_data[2] = 0x01;
663 p_rsp_data[3] = 0x00;
664 phNxpNciHal_print_packet("RECV", p_rsp_data, 4);
665 status = NFCSTATUS_FAILED;
666 #endif
667 } else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x03) {
668 NXPLOG_NCIHAL_D("EmvCo Poll mode - Discover map only for A and B");
669 p_cmd_data[2] = 0x05;
670 p_cmd_data[3] = 0x02;
671 p_cmd_data[4] = 0x00;
672 p_cmd_data[5] = 0x01;
673 p_cmd_data[6] = 0x01;
674 p_cmd_data[7] = 0x01;
675 *cmd_len = 8;
676 }
677 }
678
679 if (*cmd_len <= (NCI_MAX_DATA_LEN - 3) &&
680 bEnableMfcReader && p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x00) {
681 NXPLOG_NCIHAL_D("Going through extns - Adding Mifare in RF Discovery");
682 p_cmd_data[2] += 3;
683 p_cmd_data[3] += 1;
684 p_cmd_data[*cmd_len] = 0x80;
685 p_cmd_data[*cmd_len + 1] = 0x01;
686 p_cmd_data[*cmd_len + 2] = 0x80;
687 *cmd_len += 3;
688 status = NFCSTATUS_SUCCESS;
689 bEnableMfcExtns = false;
690 NXPLOG_NCIHAL_D(
691 "Going through extns - Adding Mifare in RF Discovery - END");
692 } else if (p_cmd_data[3] == 0x81 && p_cmd_data[4] == 0x01 &&
693 p_cmd_data[5] == 0x03) {
694 if (nxpncihal_ctrl.nci_info.nci_version != NCI_VERSION_2_0) {
695 NXPLOG_NCIHAL_D("> Going through workaround - set host list");
696
697 *cmd_len = 8;
698
699 p_cmd_data[2] = 0x05;
700 p_cmd_data[6] = 0x02;
701 p_cmd_data[7] = 0xC0;
702
703 NXPLOG_NCIHAL_D("> Going through workaround - set host list - END");
704 status = NFCSTATUS_SUCCESS;
705 }
706 } else if (icode_detected) {
707 if ((p_cmd_data[3] & 0x40) == 0x40 &&
708 (p_cmd_data[4] == 0x21 || p_cmd_data[4] == 0x22 ||
709 p_cmd_data[4] == 0x24 || p_cmd_data[4] == 0x27 ||
710 p_cmd_data[4] == 0x28 || p_cmd_data[4] == 0x29 ||
711 p_cmd_data[4] == 0x2a)) {
712 NXPLOG_NCIHAL_D("> Send EOF set");
713 icode_send_eof = 1;
714 }
715
716 if (p_cmd_data[3] == 0x20 || p_cmd_data[3] == 0x24 ||
717 p_cmd_data[3] == 0x60) {
718 NXPLOG_NCIHAL_D("> NFC ISO_15693 Proprietary CMD ");
719 p_cmd_data[3] += 0x02;
720 }
721 } else if (p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x03) {
722 NXPLOG_NCIHAL_D("> Polling Loop Started");
723 icode_detected = 0;
724 icode_send_eof = 0;
725 }
726 // 22000100
727 else if (p_cmd_data[0] == 0x22 && p_cmd_data[1] == 0x00 &&
728 p_cmd_data[2] == 0x01 && p_cmd_data[3] == 0x00) {
729 // ee_disc_done = 0x01;//Reader Over SWP event getting
730 *rsp_len = 0x05;
731 p_rsp_data[0] = 0x42;
732 p_rsp_data[1] = 0x00;
733 p_rsp_data[2] = 0x02;
734 p_rsp_data[3] = 0x00;
735 p_rsp_data[4] = 0x00;
736 phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
737 status = NFCSTATUS_FAILED;
738 }
739 // 2002 0904 3000 3100 3200 5000
740 else if ((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) &&
741 ((p_cmd_data[2] == 0x09 && p_cmd_data[3] == 0x04) /*||
742 (p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04)*/
743 )) {
744 *cmd_len += 0x01;
745 p_cmd_data[2] += 0x01;
746 p_cmd_data[9] = 0x01;
747 p_cmd_data[10] = 0x40;
748 p_cmd_data[11] = 0x50;
749 p_cmd_data[12] = 0x00;
750
751 NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config ");
752 // phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
753 NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config - End ");
754 }
755 // 20020703300031003200
756 // 2002 0301 3200
757 else if ((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) &&
758 ((p_cmd_data[2] == 0x07 && p_cmd_data[3] == 0x03) ||
759 (p_cmd_data[2] == 0x03 && p_cmd_data[3] == 0x01 &&
760 p_cmd_data[4] == 0x32))) {
761 NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config ");
762 phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
763 *rsp_len = 5;
764 p_rsp_data[0] = 0x40;
765 p_rsp_data[1] = 0x02;
766 p_rsp_data[2] = 0x02;
767 p_rsp_data[3] = 0x00;
768 p_rsp_data[4] = 0x00;
769
770 phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
771 status = NFCSTATUS_FAILED;
772 NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config - End ");
773 }
774
775 // 2002 0D04 300104 310100 320100 500100
776 // 2002 0401 320100
777 else if ((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) &&
778 (
779 /*(p_cmd_data[2] == 0x0D && p_cmd_data[3] == 0x04)*/
780 (p_cmd_data[2] == 0x04 && p_cmd_data[3] == 0x01 &&
781 p_cmd_data[4] == 0x32 && p_cmd_data[5] == 0x00))) {
782 // p_cmd_data[12] = 0x40;
783
784 NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config ");
785 phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
786 p_cmd_data[6] = 0x60;
787
788 phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
789 // status = NFCSTATUS_FAILED;
790 NXPLOG_NCIHAL_D("> Going through workaround - Dirty Set Config - End ");
791 } else if (*cmd_len <= (NCI_MAX_DATA_LEN - 3) &&
792 p_cmd_data[0] == 0x21 && p_cmd_data[1] == 0x00) {
793 NXPLOG_NCIHAL_D(
794 "> Going through workaround - Add Mifare Classic in Discovery Map");
795 p_cmd_data[*cmd_len] = 0x80;
796 p_cmd_data[*cmd_len + 1] = 0x01;
797 p_cmd_data[*cmd_len + 2] = 0x80;
798 p_cmd_data[5] = 0x01;
799 p_cmd_data[6] = 0x01;
800 p_cmd_data[2] += 3;
801 p_cmd_data[3] += 1;
802 *cmd_len += 3;
803 } else if (*cmd_len == 3 && p_cmd_data[0] == 0x00 && p_cmd_data[1] == 0x00 &&
804 p_cmd_data[2] == 0x00) {
805 NXPLOG_NCIHAL_D("> Going through workaround - ISO-DEP Presence Check ");
806 p_cmd_data[0] = 0x2F;
807 p_cmd_data[1] = 0x11;
808 p_cmd_data[2] = 0x00;
809 status = NFCSTATUS_SUCCESS;
810 NXPLOG_NCIHAL_D(
811 "> Going through workaround - ISO-DEP Presence Check - End");
812 }
813 #if 0
814 else if ( (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02 ) &&
815 ((p_cmd_data[2] == 0x09 && p_cmd_data[3] == 0x04) ||
816 (p_cmd_data[2] == 0x0B && p_cmd_data[3] == 0x05) ||
817 (p_cmd_data[2] == 0x07 && p_cmd_data[3] == 0x02) ||
818 (p_cmd_data[2] == 0x0A && p_cmd_data[3] == 0x03) ||
819 (p_cmd_data[2] == 0x0A && p_cmd_data[3] == 0x04) ||
820 (p_cmd_data[2] == 0x05 && p_cmd_data[3] == 0x02))
821 )
822 {
823 NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config ");
824 phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
825 *rsp_len = 5;
826 p_rsp_data[0] = 0x40;
827 p_rsp_data[1] = 0x02;
828 p_rsp_data[2] = 0x02;
829 p_rsp_data[3] = 0x00;
830 p_rsp_data[4] = 0x00;
831
832 phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
833 status = NFCSTATUS_FAILED;
834 NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End ");
835 }
836
837 else if((p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x02) &&
838 ((p_cmd_data[3] == 0x00) ||
839 ((*cmd_len >= 0x06) && (p_cmd_data[5] == 0x00)))) /*If the length of the first param id is zero don't allow*/
840 {
841 NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config ");
842 phNxpNciHal_print_packet("SEND", p_cmd_data, *cmd_len);
843 *rsp_len = 5;
844 p_rsp_data[0] = 0x40;
845 p_rsp_data[1] = 0x02;
846 p_rsp_data[2] = 0x02;
847 p_rsp_data[3] = 0x00;
848 p_rsp_data[4] = 0x00;
849
850 phNxpNciHal_print_packet("RECV", p_rsp_data, 5);
851 status = NFCSTATUS_FAILED;
852 NXPLOG_NCIHAL_D ("> Going through workaround - Dirty Set Config - End ");
853 }
854 #endif
855 else if ((wFwVerRsp & 0x0000FFFF) == wFwVer) {
856 /* skip CORE_RESET and CORE_INIT from Brcm */
857 if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x00 &&
858 p_cmd_data[2] == 0x01 && p_cmd_data[3] == 0x01) {
859 // *rsp_len = 6;
860 //
861 // NXPLOG_NCIHAL_D("> Going - core reset optimization");
862 //
863 // p_rsp_data[0] = 0x40;
864 // p_rsp_data[1] = 0x00;
865 // p_rsp_data[2] = 0x03;
866 // p_rsp_data[3] = 0x00;
867 // p_rsp_data[4] = 0x10;
868 // p_rsp_data[5] = 0x01;
869 //
870 // status = NFCSTATUS_FAILED;
871 // NXPLOG_NCIHAL_D("> Going - core reset optimization - END");
872 }
873 /* CORE_INIT */
874 else if (p_cmd_data[0] == 0x20 && p_cmd_data[1] == 0x01 &&
875 p_cmd_data[2] == 0x00) {
876 }
877 }
878
879
880 return status;
881 }
882
883 /******************************************************************************
884 * Function phNxpNciHal_send_ext_cmd
885 *
886 * Description This function send the extension command to NFCC. No
887 * response is checked by this function but it waits for
888 * the response to come.
889 *
890 * Returns Returns NFCSTATUS_SUCCESS if sending cmd is successful and
891 * response is received.
892 *
893 ******************************************************************************/
phNxpNciHal_send_ext_cmd(uint16_t cmd_len,uint8_t * p_cmd)894 NFCSTATUS phNxpNciHal_send_ext_cmd(uint16_t cmd_len, uint8_t* p_cmd) {
895 NFCSTATUS status = NFCSTATUS_FAILED;
896 HAL_ENABLE_EXT();
897 nxpncihal_ctrl.cmd_len = cmd_len;
898 memcpy(nxpncihal_ctrl.p_cmd_data, p_cmd, cmd_len);
899 status = phNxpNciHal_process_ext_cmd_rsp(nxpncihal_ctrl.cmd_len,
900 nxpncihal_ctrl.p_cmd_data);
901 HAL_DISABLE_EXT();
902
903 return status;
904 }
905
906 /******************************************************************************
907 * Function phNxpNciHal_send_ese_hal_cmd
908 *
909 * Description This function send the extension command to NFCC. No
910 * response is checked by this function but it waits for
911 * the response to come.
912 *
913 * Returns Returns NFCSTATUS_SUCCESS if sending cmd is successful and
914 * response is received.
915 *
916 ******************************************************************************/
phNxpNciHal_send_ese_hal_cmd(uint16_t cmd_len,uint8_t * p_cmd)917 NFCSTATUS phNxpNciHal_send_ese_hal_cmd(uint16_t cmd_len, uint8_t* p_cmd) {
918 NFCSTATUS status = NFCSTATUS_FAILED;
919 if (cmd_len > NCI_MAX_DATA_LEN) {
920 NXPLOG_NCIHAL_E("cmd_len exceeds limit NCI_MAX_DATA_LEN");
921 return status;
922 }
923 nxpncihal_ctrl.cmd_len = cmd_len;
924 memcpy(nxpncihal_ctrl.p_cmd_data, p_cmd, cmd_len);
925 status = phNxpNciHal_process_ext_cmd_rsp(nxpncihal_ctrl.cmd_len,
926 nxpncihal_ctrl.p_cmd_data);
927 return status;
928 }
929
930 /******************************************************************************
931 * Function hal_extns_write_rsp_timeout_cb
932 *
933 * Description Timer call back function
934 *
935 * Returns None
936 *
937 ******************************************************************************/
hal_extns_write_rsp_timeout_cb(uint32_t timerId,void * pContext)938 static void hal_extns_write_rsp_timeout_cb(uint32_t timerId, void* pContext) {
939 UNUSED(timerId);
940 UNUSED(pContext);
941 NXPLOG_NCIHAL_D("hal_extns_write_rsp_timeout_cb - write timeout!!!");
942 nxpncihal_ctrl.ext_cb_data.status = NFCSTATUS_FAILED;
943 usleep(1);
944 sem_post(&(nxpncihal_ctrl.syncSpiNfc));
945 SEM_POST(&(nxpncihal_ctrl.ext_cb_data));
946
947 return;
948 }
949