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