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