1 /*
2  * Copyright 2019-2024 NXP
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 
17 #include "phNxpNciHal_extOperations.h"
18 
19 #include <phNfcNciConstants.h>
20 #include <phNxpLog.h>
21 #include <phNxpNciHal_Adaptation.h>
22 #include <phTmlNfc.h>
23 
24 #include "ObserveMode.h"
25 #include "phNfcCommon.h"
26 #include "phNxpNciHal_IoctlOperations.h"
27 #include "phNxpNciHal_ULPDet.h"
28 
29 #define NCI_HEADER_SIZE 3
30 #define NCI_SE_CMD_LEN 4
31 nxp_nfc_config_ext_t config_ext;
32 static vector<uint8_t> uicc1HciParams(0);
33 static vector<uint8_t> uicc2HciParams(0);
34 static vector<uint8_t> uiccHciCeParams(0);
35 extern phNxpNciHal_Control_t nxpncihal_ctrl;
36 extern phTmlNfc_Context_t* gpphTmlNfc_Context;
37 extern void* RfFwRegionDnld_handle;
38 extern NFCSTATUS phNxpNciHal_ext_send_sram_config_to_flash();
39 
40 /*******************************************************************************
41 **
42 ** Function         phNxpNciHal_getExtVendorConfig()
43 **
44 ** Description      this function gets and updates the extension params
45 **
46 *******************************************************************************/
phNxpNciHal_getExtVendorConfig()47 void phNxpNciHal_getExtVendorConfig() {
48   unsigned long num = 0;
49   memset(&config_ext, 0x00, sizeof(nxp_nfc_config_ext_t));
50 
51   if ((GetNxpNumValue(NAME_NXP_AUTONOMOUS_ENABLE, &num, sizeof(num)))) {
52     config_ext.autonomous_mode = (uint8_t)num;
53   }
54   if ((GetNxpNumValue(NAME_NXP_GUARD_TIMER_VALUE, &num, sizeof(num)))) {
55     config_ext.guard_timer_value = (uint8_t)num;
56   }
57 }
58 
59 /******************************************************************************
60  * Function         phNxpNciHal_updateAutonomousPwrState
61  *
62  * Description      This function can be used to update autonomous pwr state.
63  *                  num: value to check  switch off bit is set or not.
64  *
65  * Returns          uint8_t
66  *
67  ******************************************************************************/
phNxpNciHal_updateAutonomousPwrState(uint8_t num)68 uint8_t phNxpNciHal_updateAutonomousPwrState(uint8_t num) {
69   if ((config_ext.autonomous_mode == true) &&
70       ((num & SWITCH_OFF_MASK) == SWITCH_OFF_MASK)) {
71     num = (num | AUTONOMOUS_SCREEN_OFF_LOCK_MASK);
72   }
73   return num;
74 }
75 /******************************************************************************
76  * Function         phNxpNciHal_setAutonomousMode
77  *
78  * Description      This function can be used to set NFCC in autonomous mode
79  *
80  * Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
81  *                  or NFCSTATUS_FEATURE_NOT_SUPPORTED
82  *
83  ******************************************************************************/
phNxpNciHal_setAutonomousMode()84 NFCSTATUS phNxpNciHal_setAutonomousMode() {
85   if (IS_CHIP_TYPE_L(sn100u)) {
86     NXPLOG_NCIHAL_D("%s : Not applicable for chipType %s", __func__,
87                     pConfigFL->product[nfcFL.chipType]);
88     return NFCSTATUS_SUCCESS;
89   }
90   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
91   uint8_t autonomous_mode_value = 0x01;
92   if (config_ext.autonomous_mode == true) autonomous_mode_value = 0x02;
93 
94   mEEPROM_info.request_mode = SET_EEPROM_DATA;
95   mEEPROM_info.buffer = (uint8_t*)&autonomous_mode_value;
96   mEEPROM_info.bufflen = sizeof(autonomous_mode_value);
97   mEEPROM_info.request_type = EEPROM_AUTONOMOUS_MODE;
98 
99   return request_EEPROM(&mEEPROM_info);
100 }
101 /******************************************************************************
102  * Function         phNxpNciHal_setGuardTimer
103  *
104  * Description      This function can be used to set nfcc Guard timer
105  *
106  * Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
107  *
108  ******************************************************************************/
phNxpNciHal_setGuardTimer()109 NFCSTATUS phNxpNciHal_setGuardTimer() {
110   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
111   NFCSTATUS status = NFCSTATUS_FEATURE_NOT_SUPPORTED;
112 
113   if (IS_CHIP_TYPE_GE(sn100u)) {
114     if (config_ext.autonomous_mode != true) config_ext.guard_timer_value = 0x00;
115 
116     mEEPROM_info.request_mode = SET_EEPROM_DATA;
117     mEEPROM_info.buffer = &config_ext.guard_timer_value;
118     mEEPROM_info.bufflen = sizeof(config_ext.guard_timer_value);
119     mEEPROM_info.request_type = EEPROM_GUARD_TIMER;
120 
121     status = request_EEPROM(&mEEPROM_info);
122   }
123   return status;
124 }
125 
126 /******************************************************************************
127  * Function         get_system_property_se_type
128  *
129  * Description      This will read NFCEE status from system properties
130  *                  and returns status.
131  *
132  * Returns          NFCEE enabled(0x01)/disabled(0x00)
133  *
134  ******************************************************************************/
get_system_property_se_type(uint8_t se_type)135 static int8_t get_system_property_se_type(uint8_t se_type) {
136   int8_t retVal = -1;
137   char valueStr[PROPERTY_VALUE_MAX] = {0};
138   if (se_type >= NUM_SE_TYPES) return retVal;
139   int len = 0;
140   switch (se_type) {
141     case SE_TYPE_ESE:
142       len = property_get("nfc.product.support.ese", valueStr, "");
143       break;
144     case SE_TYPE_EUICC:
145       len = property_get("nfc.product.support.euicc", valueStr, "");
146       break;
147     case SE_TYPE_UICC:
148       len = property_get("nfc.product.support.uicc", valueStr, "");
149       break;
150     case SE_TYPE_UICC2:
151       len = property_get("nfc.product.support.uicc2", valueStr, "");
152       break;
153   }
154   if (strlen(valueStr) == 0 || len <= 0) {
155     return retVal;
156   }
157   retVal = atoi(valueStr);
158   return retVal;
159 }
160 
161 /******************************************************************************
162  * Function         phNxpNciHal_read_and_update_se_state
163  *
164  * Description      This will read NFCEE status from system properties
165  *                  and update to NFCC to enable/disable.
166  *
167  * Returns          none
168  *
169  ******************************************************************************/
phNxpNciHal_read_and_update_se_state()170 void phNxpNciHal_read_and_update_se_state() {
171   NFCSTATUS status = NFCSTATUS_FAILED;
172   int16_t i = 0;
173   int8_t val = -1;
174   int16_t num_se = 0;
175   uint8_t retry_cnt = 0;
176   int8_t values[NUM_SE_TYPES];
177 
178   for (i = 0; i < NUM_SE_TYPES; i++) {
179     val = get_system_property_se_type(i);
180     switch (i) {
181       case SE_TYPE_ESE:
182         NXPLOG_NCIHAL_D("Get property : SUPPORT_ESE %d", val);
183         values[SE_TYPE_ESE] = val;
184         if (val > -1) {
185           num_se++;
186         }
187         break;
188       case SE_TYPE_EUICC:
189         NXPLOG_NCIHAL_D("Get property : SUPPORT_EUICC %d", val);
190         values[SE_TYPE_EUICC] = val;
191         // Since eSE and eUICC share the same config address
192         // They account for one SE
193         if (val > -1 && values[SE_TYPE_ESE] == -1) {
194           num_se++;
195         }
196         break;
197       case SE_TYPE_UICC:
198         NXPLOG_NCIHAL_D("Get property : SUPPORT_UICC %d", val);
199         values[SE_TYPE_UICC] = val;
200         if (val > -1) {
201           num_se++;
202         }
203         break;
204       case SE_TYPE_UICC2:
205         values[SE_TYPE_UICC2] = val;
206         if (val > -1) {
207           num_se++;
208         }
209         NXPLOG_NCIHAL_D("Get property : SUPPORT_UICC2 %d", val);
210         break;
211     }
212   }
213   if (num_se < 1) {
214     return;
215   }
216   uint8_t set_cfg_cmd[NCI_HEADER_SIZE + 1 +
217                       (num_se * NCI_SE_CMD_LEN)];  // 1 for Number of Argument
218   uint8_t* index = &set_cfg_cmd[0];
219   *index++ = NCI_MT_CMD;
220   *index++ = NXP_CORE_SET_CONFIG_CMD;
221   *index++ = (num_se * NCI_SE_CMD_LEN) + 1;
222   *index++ = num_se;
223   for (i = 0; i < NUM_SE_TYPES; i++) {
224     switch (i) {
225       case SE_TYPE_ESE:
226       case SE_TYPE_EUICC:
227         if (values[SE_TYPE_ESE] == -1 && values[SE_TYPE_EUICC] == -1) {
228           // No value defined
229           break;
230         }
231         *index++ = 0xA0;
232         *index++ = 0xED;
233         *index++ = 0x01;
234 
235         *index = 0x00;
236         if (values[SE_TYPE_ESE] > -1) {
237           *index = *index | values[SE_TYPE_ESE];
238         }
239         if (values[SE_TYPE_EUICC] > -1) {
240           *index = *index | values[SE_TYPE_EUICC] << 1;
241         }
242         NXPLOG_NCIHAL_D("Combined value for eSE/eUICC is 0x%.2x", *index);
243         index++;
244         i++;  // both cases taken care
245 
246         break;
247       case SE_TYPE_UICC:
248         if (values[SE_TYPE_UICC] > -1) {
249           *index++ = 0xA0;
250           *index++ = 0xEC;
251           *index++ = 0x01;
252           *index++ = values[SE_TYPE_UICC];
253         }
254         break;
255       case SE_TYPE_UICC2:
256         if (values[SE_TYPE_UICC2] > -1) {
257           *index++ = 0xA0;
258           *index++ = 0xD4;
259           *index++ = 0x01;
260           *index++ = values[SE_TYPE_UICC2];
261         }
262         break;
263     }
264   }
265 
266   while (status != NFCSTATUS_SUCCESS && retry_cnt < 3) {
267     status = phNxpNciHal_send_ext_cmd(sizeof(set_cfg_cmd), set_cfg_cmd);
268     retry_cnt++;
269     NXPLOG_NCIHAL_E("set Cfg Retry cnt=%x", retry_cnt);
270   }
271 }
272 
273 /******************************************************************************
274  * Function         phNxpNciHal_read_fw_dw_status
275  *
276  * Description      This will read the value of fw download status flag
277  *                  from eeprom
278  *
279  * Parameters       value - this parameter will be updated with the flag
280  *                  value from eeprom.
281  *
282  * Returns          status of the read
283  *
284  ******************************************************************************/
phNxpNciHal_read_fw_dw_status(uint8_t & value)285 NFCSTATUS phNxpNciHal_read_fw_dw_status(uint8_t& value) {
286   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
287   mEEPROM_info.buffer = &value;
288   mEEPROM_info.bufflen = sizeof(value);
289   mEEPROM_info.request_type = EEPROM_FW_DWNLD;
290   mEEPROM_info.request_mode = GET_EEPROM_DATA;
291   return request_EEPROM(&mEEPROM_info);
292 }
293 
294 /******************************************************************************
295  * Function         phNxpNciHal_write_fw_dw_status
296  *
297  * Description      This will update value of fw download status flag
298  *                  to eeprom
299  *
300  * Parameters       value - this value will be updated to eeprom flag.
301  *
302  * Returns          status of the write
303  *
304  ******************************************************************************/
phNxpNciHal_write_fw_dw_status(uint8_t value)305 NFCSTATUS phNxpNciHal_write_fw_dw_status(uint8_t value) {
306   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
307   mEEPROM_info.buffer = &value;
308   mEEPROM_info.bufflen = sizeof(value);
309   mEEPROM_info.request_type = EEPROM_FW_DWNLD;
310   mEEPROM_info.request_mode = SET_EEPROM_DATA;
311   return request_EEPROM(&mEEPROM_info);
312 }
313 
314 /******************************************************************************
315  * Function         phNxpNciHal_save_uicc_params
316  *
317  * Description      This will read the UICC HCI param values
318  *                  from eeprom and store in global variable
319  *
320  * Returns          status of the read
321  *
322  ******************************************************************************/
phNxpNciHal_save_uicc_params()323 NFCSTATUS phNxpNciHal_save_uicc_params() {
324   if (IS_CHIP_TYPE_L(sn220u)) {
325     NXPLOG_NCIHAL_E("%s Not supported", __func__);
326     return NFCSTATUS_SUCCESS;
327   }
328 
329   NFCSTATUS status = NFCSTATUS_FAILED;
330 
331   /* Getting UICC2 CL params */
332   uicc1HciParams.resize(0xFF);
333   status = phNxpNciHal_get_uicc_hci_params(
334       uicc1HciParams, uicc1HciParams.size(), EEPROM_UICC1_SESSION_ID);
335   if (status != NFCSTATUS_SUCCESS) {
336     NXPLOG_NCIHAL_E("%s: Save UICC1 CLPP failed .", __func__);
337   }
338 
339   /* Getting UICC2 CL params */
340   uicc2HciParams.resize(0xFF);
341   status = phNxpNciHal_get_uicc_hci_params(
342       uicc2HciParams, uicc2HciParams.size(), EEPROM_UICC2_SESSION_ID);
343   if (status != NFCSTATUS_SUCCESS) {
344     NXPLOG_NCIHAL_E("%s: Save UICC2 CLPP failed .", __func__);
345   }
346 
347   /* Get UICC CE HCI State */
348   uiccHciCeParams.resize(0xFF);
349   status = phNxpNciHal_get_uicc_hci_params(
350       uiccHciCeParams, uiccHciCeParams.size(), EEPROM_UICC_HCI_CE_STATE);
351   if (status != NFCSTATUS_SUCCESS) {
352     NXPLOG_NCIHAL_E("%s: Save UICC_HCI_CE_STATE failed .", __func__);
353   }
354   return status;
355 }
356 
357 /******************************************************************************
358  * Function         phNxpNciHal_restore_uicc_params
359  *
360  * Description      This will set the UICC HCI param values
361  *                  back to eeprom from global variable
362  *
363  * Returns          status of the read
364  *
365  ******************************************************************************/
phNxpNciHal_restore_uicc_params()366 NFCSTATUS phNxpNciHal_restore_uicc_params() {
367   if (IS_CHIP_TYPE_L(sn220u)) {
368     NXPLOG_NCIHAL_E("%s Not supported", __func__);
369     return NFCSTATUS_SUCCESS;
370   }
371 
372   NFCSTATUS status = NFCSTATUS_FAILED;
373   if (uicc1HciParams.size() > 0) {
374     status = phNxpNciHal_set_uicc_hci_params(
375         uicc1HciParams, uicc1HciParams.size(), EEPROM_UICC1_SESSION_ID);
376     if (status != NFCSTATUS_SUCCESS) {
377       NXPLOG_NCIHAL_E("%s: Restore UICC1 CLPP failed .", __func__);
378     } else {
379       uicc1HciParams.resize(0);
380     }
381   }
382   if (uicc2HciParams.size() > 0) {
383     status = phNxpNciHal_set_uicc_hci_params(
384         uicc2HciParams, uicc2HciParams.size(), EEPROM_UICC2_SESSION_ID);
385     if (status != NFCSTATUS_SUCCESS) {
386       NXPLOG_NCIHAL_E("%s: Restore UICC2 CLPP failed .", __func__);
387     } else {
388       uicc2HciParams.resize(0);
389     }
390   }
391   if (uiccHciCeParams.size() > 0) {
392     status = phNxpNciHal_set_uicc_hci_params(
393         uiccHciCeParams, uiccHciCeParams.size(), EEPROM_UICC_HCI_CE_STATE);
394     if (status != NFCSTATUS_SUCCESS) {
395       NXPLOG_NCIHAL_E("%s: Restore UICC_HCI_CE_STATE failed .", __func__);
396     } else {
397       uiccHciCeParams.resize(0);
398     }
399   }
400   return status;
401 }
402 
403 /******************************************************************************
404  * Function         phNxpNciHal_get_uicc_hci_params
405  *
406  * Description      This will read the UICC HCI param values
407  *                  from eeprom
408  *
409  * Parameters       value - this parameter will be updated with the flag
410  *                  value from eeprom.
411  *
412  * Returns          status of the read
413  *
414  ******************************************************************************/
415 NFCSTATUS
phNxpNciHal_get_uicc_hci_params(vector<uint8_t> & ptr,uint8_t bufflen,phNxpNci_EEPROM_request_type_t uiccType)416 phNxpNciHal_get_uicc_hci_params(vector<uint8_t>& ptr, uint8_t bufflen,
417                                 phNxpNci_EEPROM_request_type_t uiccType) {
418   if (IS_CHIP_TYPE_L(sn220u)) {
419     NXPLOG_NCIHAL_E("%s Not supported", __func__);
420     return NFCSTATUS_SUCCESS;
421   }
422   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
423   mEEPROM_info.buffer = &ptr[0];
424   mEEPROM_info.bufflen = bufflen;
425   mEEPROM_info.request_type = uiccType;
426   mEEPROM_info.request_mode = GET_EEPROM_DATA;
427   NFCSTATUS status = request_EEPROM(&mEEPROM_info);
428   ptr.resize(mEEPROM_info.bufflen);
429   return status;
430 }
431 
432 /******************************************************************************
433  * Function         phNxpNciHal_set_uicc_hci_params
434  *
435  * Description      This will update the UICC HCI param values
436  *                  to eeprom
437  *
438  * Parameters       value - this value will be updated to eeprom flag.
439  *
440  * Returns          status of the write
441  *
442  *****************************************************************************/
443 NFCSTATUS
phNxpNciHal_set_uicc_hci_params(vector<uint8_t> & ptr,uint8_t bufflen,phNxpNci_EEPROM_request_type_t uiccType)444 phNxpNciHal_set_uicc_hci_params(vector<uint8_t>& ptr, uint8_t bufflen,
445                                 phNxpNci_EEPROM_request_type_t uiccType) {
446   if (IS_CHIP_TYPE_L(sn220u)) {
447     NXPLOG_NCIHAL_E("%s Not supported", __func__);
448     return NFCSTATUS_SUCCESS;
449   }
450   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
451   mEEPROM_info.buffer = &ptr[0];
452   mEEPROM_info.bufflen = bufflen;
453   mEEPROM_info.request_type = uiccType;
454   mEEPROM_info.request_mode = SET_EEPROM_DATA;
455   return request_EEPROM(&mEEPROM_info);
456 }
457 
458 /*****************************************************************************
459  * Function         phNxpNciHal_send_get_cfg
460  *
461  * Description      This function is called to get the configurations from
462  * EEPROM
463  *
464  * Params           cmd_get_cfg, Buffer to get the get command
465  *                  cmd_len,     Length of the command
466  * Returns          SUCCESS/FAILURE
467  *
468  *
469  *****************************************************************************/
phNxpNciHal_send_get_cfg(const uint8_t * cmd_get_cfg,long cmd_len)470 NFCSTATUS phNxpNciHal_send_get_cfg(const uint8_t* cmd_get_cfg, long cmd_len) {
471   NXPLOG_NCIHAL_D("%s Enter", __func__);
472   NFCSTATUS status = NFCSTATUS_FAILED;
473   uint8_t retry_cnt = 0;
474 
475   if (cmd_get_cfg == NULL || cmd_len <= NCI_GET_CONFI_MIN_LEN) {
476     NXPLOG_NCIHAL_E("%s invalid command..! returning... ", __func__);
477     return status;
478   }
479 
480   do {
481     status = phNxpNciHal_send_ext_cmd(cmd_len, (uint8_t*)cmd_get_cfg);
482   } while ((status != NFCSTATUS_SUCCESS) &&
483            (retry_cnt++ < NXP_MAX_RETRY_COUNT));
484 
485   NXPLOG_NCIHAL_D("%s status : 0x%02X", __func__, status);
486   return status;
487 }
488 
489 /*****************************************************************************
490  * Function         phNxpNciHal_configure_merge_sak
491  *
492  * Description      This function is called to apply iso_dep sak merge settings
493  *                  as per the config option NAME_NXP_ISO_DEP_MERGE_SAK
494  *
495  * Params           None
496 
497  * Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
498  *
499  *****************************************************************************/
phNxpNciHal_configure_merge_sak()500 NFCSTATUS phNxpNciHal_configure_merge_sak() {
501   if (IS_CHIP_TYPE_L(sn100u)) {
502     NXPLOG_NCIHAL_D("%s : Not applicable for chipType %s", __func__,
503                     pConfigFL->product[nfcFL.chipType]);
504     return NFCSTATUS_SUCCESS;
505   }
506   long retlen = 0;
507   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
508   NXPLOG_NCIHAL_D("Performing ISODEP sak merge settings");
509   uint8_t val = 0;
510 
511   if (!GetNxpNumValue(NAME_NXP_ISO_DEP_MERGE_SAK, (void*)&retlen,
512                       sizeof(retlen))) {
513     retlen = 0x01;
514     NXPLOG_NCIHAL_D(
515         "ISO_DEP_MERGE_SAK not found. default shall be enabled : 0x%02lx",
516         retlen);
517   }
518   val = (uint8_t)retlen;
519   mEEPROM_info.buffer = &val;
520   mEEPROM_info.bufflen = sizeof(val);
521   mEEPROM_info.request_type = EEPROM_ISODEP_MERGE_SAK;
522   mEEPROM_info.request_mode = SET_EEPROM_DATA;
523   return request_EEPROM(&mEEPROM_info);
524 }
525 #if (NXP_SRD == TRUE)
526 /******************************************************************************
527  * Function         phNxpNciHal_setSrdtimeout
528  *
529  * Description      This function can be used to set srd SRD Timeout.
530  *
531  * Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS or
532  *                  NFCSTATUS_FEATURE_NOT_SUPPORTED
533  *
534  ******************************************************************************/
phNxpNciHal_setSrdtimeout()535 NFCSTATUS phNxpNciHal_setSrdtimeout() {
536   long retlen = 0;
537   uint8_t* buffer = nullptr;
538   long bufflen = 260;
539   const int NXP_SRD_TIMEOUT_BUF_LEN = 2;
540   const uint16_t TIMEOUT_MASK = 0xFFFF;
541   const uint16_t MAX_TIMEOUT_VALUE = 0xFD70;
542   uint16_t isValid_timeout;
543   uint8_t timeout_buffer[NXP_SRD_TIMEOUT_BUF_LEN];
544   NFCSTATUS status = NFCSTATUS_FEATURE_NOT_SUPPORTED;
545   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
546 
547   NXPLOG_NCIHAL_D("Performing SRD Timeout settings");
548 
549   buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t));
550   if (NULL == buffer) {
551     return NFCSTATUS_FAILED;
552   }
553   memset(buffer, 0x00, bufflen);
554   if (GetNxpByteArrayValue(NAME_NXP_SRD_TIMEOUT, (char*)buffer, bufflen,
555                            &retlen)) {
556     if (retlen == NXP_SRD_TIMEOUT_BUF_LEN) {
557       isValid_timeout = ((buffer[1] << 8) & TIMEOUT_MASK);
558       isValid_timeout = (isValid_timeout | buffer[0]);
559       if (isValid_timeout > MAX_TIMEOUT_VALUE) {
560         /*if timeout is setting more than 18hrs
561          * than setting to MAX limit 0xFD70*/
562         buffer[0] = 0x70;
563         buffer[1] = 0xFD;
564       }
565       memcpy(&timeout_buffer, buffer, NXP_SRD_TIMEOUT_BUF_LEN);
566       mEEPROM_info.buffer = timeout_buffer;
567       mEEPROM_info.bufflen = sizeof(timeout_buffer);
568       mEEPROM_info.request_type = EEPROM_SRD_TIMEOUT;
569       mEEPROM_info.request_mode = SET_EEPROM_DATA;
570       status = request_EEPROM(&mEEPROM_info);
571     }
572   }
573   if (buffer != NULL) {
574     free(buffer);
575     buffer = NULL;
576   }
577 
578   return status;
579 }
580 #endif
581 
582 /******************************************************************************
583  * Function         phNxpNciHal_setExtendedFieldMode
584  *
585  * Description      This function can be used to set nfcc extended field mode
586  *
587  * Params           requestedBy CONFIG to set it from the CONFIGURATION
588  *                              API  to set it from ObserverMode API
589  *
590  * Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS or
591  *                  NFCSTATUS_FEATURE_NOT_SUPPORTED
592  *
593  ******************************************************************************/
phNxpNciHal_setExtendedFieldMode()594 NFCSTATUS phNxpNciHal_setExtendedFieldMode() {
595   const uint8_t enableWithOutCMAEvents = 0x01;
596   const uint8_t enableWithCMAEvents = 0x03;
597   const uint8_t disableEvents = 0x00;
598   uint8_t extended_field_mode = disableEvents;
599   NFCSTATUS status = NFCSTATUS_FEATURE_NOT_SUPPORTED;
600 
601   if (IS_CHIP_TYPE_GE(sn100u) &&
602       GetNxpNumValue(NAME_NXP_EXTENDED_FIELD_DETECT_MODE, &extended_field_mode,
603                      sizeof(extended_field_mode))) {
604     if (extended_field_mode == enableWithOutCMAEvents ||
605         extended_field_mode == enableWithCMAEvents ||
606         extended_field_mode == disableEvents) {
607       phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = SET_EEPROM_DATA};
608       mEEPROM_info.buffer = &extended_field_mode;
609       mEEPROM_info.bufflen = sizeof(extended_field_mode);
610       mEEPROM_info.request_type = EEPROM_EXT_FIELD_DETECT_MODE;
611       status = request_EEPROM(&mEEPROM_info);
612     } else {
613       NXPLOG_NCIHAL_E("Invalid Extended Field Mode in config");
614     }
615   }
616   return status;
617 }
618 
619 /*******************************************************************************
620 **
621 ** Function         phNxpNciHal_configGPIOControl()
622 **
623 ** Description      Helper function to configure GPIO control
624 **
625 ** Parameters       gpioControl - Byte array with first two bytes are used to
626 **                  configure gpio for specific functionality (ex:ULPDET,
627 **                  GPIO LEVEL ...) and 3rd byte indicates the level of GPIO
628 **                  to be set.
629 **                  len        - Len of byte array
630 **
631 ** Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
632 *******************************************************************************/
phNxpNciHal_configGPIOControl(uint8_t gpioCtrl[],uint8_t len)633 NFCSTATUS phNxpNciHal_configGPIOControl(uint8_t gpioCtrl[], uint8_t len) {
634   NFCSTATUS status = NFCSTATUS_SUCCESS;
635 
636   if (len == 0) {
637     return NFCSTATUS_INVALID_PARAMETER;
638   }
639   if (nfcFL.chipType <= sn100u) {
640     NXPLOG_NCIHAL_D("%s : Not applicable for chipType %s", __func__,
641                     pConfigFL->product[nfcFL.chipType]);
642     return status;
643   }
644   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
645 
646   mEEPROM_info.request_mode = SET_EEPROM_DATA;
647   mEEPROM_info.buffer = (uint8_t*)gpioCtrl;
648   // First two bytes decides purpose of GPIO config
649   // LIKE ULPDET, GPIO CTRL
650   mEEPROM_info.bufflen = 2;
651   mEEPROM_info.request_type = EEPROM_CONF_GPIO_CTRL;
652 
653   status = request_EEPROM(&mEEPROM_info);
654   if (status != NFCSTATUS_SUCCESS) {
655     NXPLOG_NCIHAL_D("%s : Failed to Enable GPIO ctrl", __func__);
656     return status;
657   }
658   if (len >= 3) {
659     mEEPROM_info.request_mode = SET_EEPROM_DATA;
660     mEEPROM_info.buffer = gpioCtrl + 2;
661     // Last byte contains bitmask of GPIO 2/3 values.
662     mEEPROM_info.bufflen = 1;
663     mEEPROM_info.request_type = EEPROM_SET_GPIO_VALUE;
664 
665     status = request_EEPROM(&mEEPROM_info);
666     if (status != NFCSTATUS_SUCCESS) {
667       NXPLOG_NCIHAL_D("%s : Failed to set GPIO ctrl", __func__);
668     }
669   }
670   return status;
671 }
672 
673 /*******************************************************************************
674 **
675 ** Function         phNxpNciHal_decodeGpioStatus()
676 **
677 ** Description      this function decodes gpios status of the nfc pins
678 **
679 *******************************************************************************/
phNxpNciHal_decodeGpioStatus(void)680 void phNxpNciHal_decodeGpioStatus(void) {
681   NFCSTATUS status = NFCSTATUS_SUCCESS;
682   status = phNxpNciHal_GetNfcGpiosStatus(&gpios_data.gpios_status_data);
683   if (status != NFCSTATUS_SUCCESS) {
684     NXPLOG_NCIHAL_E("Get Gpio Status: Failed");
685   } else {
686     NXPLOG_NCIR_D("%s: NFC_IRQ = %d NFC_VEN = %d NFC_FW_DWL =%d", __func__,
687                   gpios_data.platform_gpios_status.irq,
688                   gpios_data.platform_gpios_status.ven,
689                   gpios_data.platform_gpios_status.fw_dwl);
690   }
691 }
692 
693 /******************************************************************************
694  * Function         phNxpNciHal_setDCDCConfig()
695  *
696  * Description      Sets DCDC On/Off
697  *
698  * Returns          void
699  *
700  *****************************************************************************/
701 
phNxpNciHal_setDCDCConfig(void)702 void phNxpNciHal_setDCDCConfig(void) {
703   uint8_t NXP_CONF_DCDC_ON[] = {
704       0x20, 0x02, 0xDA, 0x04, 0xA0, 0x0E, 0x30, 0x7B, 0x00, 0xDE, 0xBA, 0xC4,
705       0xC4, 0xC9, 0x00, 0x00, 0x00, 0xA8, 0x00, 0x37, 0xBE, 0xFF, 0xFF, 0x03,
706       0x00, 0x00, 0x00, 0x28, 0x28, 0x28, 0x28, 0x0A, 0x50, 0x50, 0x00, 0x0A,
707       0x64, 0x0D, 0x08, 0x04, 0x81, 0x0E, 0x20, 0x00, 0x00, 0x00, 0x00, 0x17,
708       0x33, 0x14, 0x07, 0x84, 0x38, 0x20, 0x0F, 0xA0, 0xA4, 0x85, 0x14, 0x00,
709       0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0B, 0x00, 0x0E,
710       0x00, 0x12, 0x00, 0x15, 0x00, 0x19, 0x00, 0x1D, 0x00, 0x21, 0x00, 0x24,
711       0x00, 0x28, 0x00, 0x2B, 0x00, 0x2E, 0x00, 0x32, 0x00, 0x35, 0x00, 0x38,
712       0x00, 0x3B, 0x00, 0x3E, 0x00, 0x41, 0x00, 0x44, 0x00, 0x47, 0x00, 0x4A,
713       0x00, 0x4C, 0x00, 0x4F, 0x00, 0x51, 0x00, 0x53, 0x00, 0x56, 0x00, 0x58,
714       0x00, 0x5A, 0x00, 0x5C, 0x00, 0x5E, 0x00, 0x5F, 0x00, 0x61, 0x00, 0x63,
715       0x00, 0x64, 0x00, 0x66, 0x00, 0x67, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B,
716       0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6E, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x71,
717       0x00, 0x72, 0x00, 0x73, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x75,
718       0x00, 0x76, 0x00, 0x76, 0x00, 0x77, 0x00, 0x77, 0x00, 0x78, 0x00, 0x78,
719       0x00, 0x79, 0x00, 0x79, 0x00, 0x79, 0x00, 0x7A, 0x00, 0x7A, 0x00, 0xA0,
720       0x10, 0x11, 0x01, 0x06, 0x74, 0x78, 0x00, 0x00, 0x41, 0xF4, 0xC5, 0x00,
721       0xFF, 0x04, 0x00, 0x04, 0x80, 0x5E, 0x01, 0xA0, 0x11, 0x07, 0x01, 0x80,
722       0x32, 0x01, 0xC8, 0x03, 0x00};
723 
724   uint8_t NXP_CONF_DCDC_OFF[] = {
725       0x20, 0x02, 0xDA, 0x04, 0xA0, 0x0E, 0x30, 0x7B, 0x00, 0x9E, 0xBA, 0x01,
726       0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x37, 0xBE, 0xFF, 0xFF, 0x03,
727       0x00, 0x00, 0x00, 0x12, 0x12, 0x12, 0x12, 0x0A, 0x50, 0x50, 0x00, 0x0A,
728       0x64, 0x0D, 0x08, 0x04, 0x81, 0x0E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x17,
729       0x33, 0x14, 0x07, 0x84, 0x38, 0x20, 0x0F, 0xA0, 0xA4, 0x85, 0x14, 0x00,
730       0x01, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x0B, 0x00, 0x0E,
731       0x00, 0x12, 0x00, 0x15, 0x00, 0x19, 0x00, 0x1D, 0x00, 0x21, 0x00, 0x24,
732       0x00, 0x28, 0x00, 0x2B, 0x00, 0x2E, 0x00, 0x32, 0x00, 0x35, 0x00, 0x38,
733       0x00, 0x3B, 0x00, 0x3E, 0x00, 0x41, 0x00, 0x44, 0x00, 0x47, 0x00, 0x4A,
734       0x00, 0x4C, 0x00, 0x4F, 0x00, 0x51, 0x00, 0x53, 0x00, 0x56, 0x00, 0x58,
735       0x00, 0x5A, 0x00, 0x5C, 0x00, 0x5E, 0x00, 0x5F, 0x00, 0x61, 0x00, 0x63,
736       0x00, 0x64, 0x00, 0x66, 0x00, 0x67, 0x00, 0x69, 0x00, 0x6A, 0x00, 0x6B,
737       0x00, 0x6C, 0x00, 0x6D, 0x00, 0x6E, 0x00, 0x6F, 0x00, 0x70, 0x00, 0x71,
738       0x00, 0x72, 0x00, 0x73, 0x00, 0x73, 0x00, 0x74, 0x00, 0x75, 0x00, 0x75,
739       0x00, 0x76, 0x00, 0x76, 0x00, 0x77, 0x00, 0x77, 0x00, 0x78, 0x00, 0x78,
740       0x00, 0x79, 0x00, 0x79, 0x00, 0x79, 0x00, 0x7A, 0x00, 0x7A, 0x00, 0xA0,
741       0x10, 0x11, 0x01, 0x06, 0x74, 0x78, 0x00, 0x00, 0x41, 0xF4, 0xC5, 0x00,
742       0xFF, 0x04, 0x00, 0x04, 0x80, 0x5E, 0x01, 0xA0, 0x11, 0x07, 0x01, 0x80,
743       0x32, 0x01, 0xC8, 0x03, 0x00};
744   unsigned long enable = 0;
745   NFCSTATUS status = NFCSTATUS_FAILED;
746   if (!GetNxpNumValue(NAME_NXP_ENABLE_DCDC_ON, (void*)&enable,
747                       sizeof(enable))) {
748     NXPLOG_NCIHAL_D("NAME_NXP_ENABLE_DCDC_ON not found:");
749     return;
750   }
751   NXPLOG_NCIHAL_D("Perform DCDC config");
752   if (enable == 1) {
753     // DCDC On
754     status = phNxpNciHal_send_ext_cmd(sizeof(NXP_CONF_DCDC_ON),
755                                       &(NXP_CONF_DCDC_ON[0]));
756   } else {
757     // DCDC Off
758     status = phNxpNciHal_send_ext_cmd(sizeof(NXP_CONF_DCDC_OFF),
759                                       &(NXP_CONF_DCDC_OFF[0]));
760   }
761   if (status != NFCSTATUS_SUCCESS) {
762     NXPLOG_NCIHAL_E("SetConfig for DCDC failed");
763   }
764 }
765 
766 /*******************************************************************************
767 **
768 ** Function         phNxpNciHal_isVendorSpecificCommand()
769 **
770 ** Description      this function checks vendor specific command or not
771 **
772 ** Returns          true if the command is vendor specific otherwise false
773 *******************************************************************************/
phNxpNciHal_isVendorSpecificCommand(uint16_t data_len,const uint8_t * p_data)774 bool phNxpNciHal_isVendorSpecificCommand(uint16_t data_len,
775                                          const uint8_t* p_data) {
776   if (data_len > 3 && p_data[NCI_GID_INDEX] == (NCI_MT_CMD | NCI_GID_PROP) &&
777       p_data[NCI_OID_INDEX] == NCI_PROP_NTF_ANDROID_OID) {
778     return true;
779   }
780   return false;
781 }
782 
783 /*******************************************************************************
784 **
785 ** Function         phNxpNciHal_handleVendorSpecificCommand()
786 **
787 ** Description      This handles the vendor specific command
788 **
789 ** Returns          It returns number of bytes received.
790 *******************************************************************************/
phNxpNciHal_handleVendorSpecificCommand(uint16_t data_len,const uint8_t * p_data)791 int phNxpNciHal_handleVendorSpecificCommand(uint16_t data_len,
792                                             const uint8_t* p_data) {
793   if (data_len > 4 &&
794       p_data[NCI_MSG_INDEX_FOR_FEATURE] == NCI_ANDROID_POWER_SAVING) {
795     return phNxpNciHal_handleULPDetCommand(data_len, p_data);
796   } else if (data_len > 4 &&
797              p_data[NCI_MSG_INDEX_FOR_FEATURE] == NCI_ANDROID_OBSERVER_MODE) {
798     return handleObserveMode(data_len, p_data);
799   } else if (data_len >= 4 && p_data[NCI_MSG_INDEX_FOR_FEATURE] ==
800                                   NCI_ANDROID_GET_OBSERVER_MODE_STATUS) {
801     // 2F 0C 01 04 => ObserveMode Status Command length is 4 Bytes
802     return handleGetObserveModeStatus(data_len, p_data);
803   } else if (data_len >= 4 &&
804              p_data[NCI_MSG_INDEX_FOR_FEATURE] == NCI_ANDROID_GET_CAPABILITY) {
805     // 2F 0C 01 00 => GetCapability Command length is 4 Bytes
806     return handleGetCapability(data_len, p_data);
807   } else {
808     return phNxpNciHal_write_internal(data_len, p_data);
809   }
810 }
811 
812 /*******************************************************************************
813 **
814 ** Function         phNxpNciHal_vendorSpecificCallback()
815 **
816 ** Params           oid, opcode, data
817 **
818 ** Description      This function sends response to Vendor Specific commands
819 **
820 *******************************************************************************/
phNxpNciHal_vendorSpecificCallback(int oid,int opcode,vector<uint8_t> data)821 void phNxpNciHal_vendorSpecificCallback(int oid, int opcode,
822                                         vector<uint8_t> data) {
823   static phLibNfc_Message_t msg;
824   nxpncihal_ctrl.vendor_msg[0] = (uint8_t)(NCI_GID_PROP | NCI_MT_RSP);
825   nxpncihal_ctrl.vendor_msg[1] = oid;
826   nxpncihal_ctrl.vendor_msg[2] = 1 + (int)data.size();
827   nxpncihal_ctrl.vendor_msg[3] = opcode;
828   if ((int)data.size() > 0) {
829     memcpy(&nxpncihal_ctrl.vendor_msg[4], data.data(),
830            data.size() * sizeof(uint8_t));
831   }
832   nxpncihal_ctrl.vendor_msg_len = 4 + (int)data.size();
833 
834   msg.eMsgType = NCI_HAL_VENDOR_MSG;
835   msg.pMsgData = NULL;
836   msg.Size = 0;
837   phNxpNciHal_print_packet("RECV", nxpncihal_ctrl.vendor_msg,
838                            nxpncihal_ctrl.vendor_msg_len,
839                            RfFwRegionDnld_handle == NULL);
840   phTmlNfc_DeferredCall(gpphTmlNfc_Context->dwCallbackThreadId,
841                         (phLibNfc_Message_t*)&msg);
842 }
843 
844 /*******************************************************************************
845 **
846 ** Function         phNxpNciHal_isObserveModeSupported()
847 **
848 ** Description      check's the observe mode supported or not based on the
849 **                  config value
850 **
851 ** Returns          bool: true if supported, otherwise false
852 *******************************************************************************/
phNxpNciHal_isObserveModeSupported()853 bool phNxpNciHal_isObserveModeSupported() {
854   const uint8_t enableWithCMAEvents = 0x03;
855   const uint8_t disableEvents = 0x00;
856   uint8_t extended_field_mode = disableEvents;
857   if (IS_CHIP_TYPE_GE(sn100u) &&
858       GetNxpNumValue(NAME_NXP_EXTENDED_FIELD_DETECT_MODE, &extended_field_mode,
859                      sizeof(extended_field_mode))) {
860     if (extended_field_mode == enableWithCMAEvents) {
861       return true;
862     } else {
863       NXPLOG_NCIHAL_E("Invalid Extended Field Mode in config");
864     }
865   }
866   return false;
867 }
868 
869 /*******************************************************************************
870  *
871  * Function         handleGetCapability()
872  *
873  * Description      It frames the capability for the below features
874  *                  1. Observe mode
875  *                  2. Polling frame notification
876  *                  3. Power saving mode
877  *                  4. Auotransact polling loop filter
878  *
879  * Returns          It returns number of bytes received.
880  *
881  ******************************************************************************/
handleGetCapability(uint16_t data_len,const uint8_t * p_data)882 int handleGetCapability(uint16_t data_len, const uint8_t* p_data) {
883   // 2F 0C 01 00 => GetCapability Command length is 4 Bytes
884   if (data_len < 4) {
885     return 0;
886   }
887 
888   // First byte is status is ok
889   // next 2 bytes is version for Android requirements
890   vector<uint8_t> capability = {0x00, 0x00, 0x00};
891   capability.push_back(4);  // 4 capability event's
892   // Observe mode
893   capability.push_back(nfcFL.nfccCap.OBSERVE_MODE.id);
894   capability.push_back(nfcFL.nfccCap.OBSERVE_MODE.len);
895   capability.push_back(nfcFL.nfccCap.OBSERVE_MODE.val);
896   // Polling frame notification
897   capability.push_back(nfcFL.nfccCap.POLLING_FRAME_NOTIFICATION.id);
898   capability.push_back(nfcFL.nfccCap.POLLING_FRAME_NOTIFICATION.len);
899   capability.push_back(nfcFL.nfccCap.POLLING_FRAME_NOTIFICATION.val);
900   // Power saving mode
901   capability.push_back(nfcFL.nfccCap.POWER_SAVING.id);
902   capability.push_back(nfcFL.nfccCap.POWER_SAVING.len);
903   capability.push_back(nfcFL.nfccCap.POWER_SAVING.val);
904   // Auotransact polling loop filter
905   capability.push_back(nfcFL.nfccCap.AUTOTRANSACT_PLF.id);
906   capability.push_back(nfcFL.nfccCap.AUTOTRANSACT_PLF.len);
907   capability.push_back(nfcFL.nfccCap.AUTOTRANSACT_PLF.val);
908 
909   phNxpNciHal_vendorSpecificCallback(p_data[NCI_OID_INDEX],
910                                      p_data[NCI_MSG_INDEX_FOR_FEATURE],
911                                      std::move(capability));
912   return p_data[NCI_MSG_LEN_INDEX];
913 }
914