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