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