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