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