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