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