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