1 /*
2  * Copyright (C) 2019-2020 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 
17 #include "phNxpNciHal_extOperations.h"
18 #include <phNxpLog.h>
19 #include <phNxpNciHal_ext.h>
20 #include "phNfcCommon.h"
21 #include "phNxpNciHal_IoctlOperations.h"
22 
23 #define NCI_HEADER_SIZE 3
24 #define NCI_SE_CMD_LEN 4
25 nxp_nfc_config_ext_t config_ext;
26 /******************************************************************************
27  * Function         phNxpNciHal_updateAutonomousPwrState
28  *
29  * Description      This function can be used to update autonomous pwr state.
30  *                  num: value to check  switch off bit is set or not.
31  *
32  * Returns          uint8_t
33  *
34  ******************************************************************************/
phNxpNciHal_updateAutonomousPwrState(uint8_t num)35 uint8_t phNxpNciHal_updateAutonomousPwrState(uint8_t num) {
36   if ((config_ext.autonomous_mode == true) &&
37       ((num & SWITCH_OFF_MASK) == SWITCH_OFF_MASK)) {
38     num = (num | AUTONOMOUS_SCREEN_OFF_LOCK_MASK);
39   }
40   return num;
41 }
42 /******************************************************************************
43  * Function         phNxpNciHal_setAutonomousMode
44  *
45  * Description      This function can be used to set NFCC in autonomous mode
46  *
47  * Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
48  *                  or NFCSTATUS_FEATURE_NOT_SUPPORTED
49  *
50  ******************************************************************************/
phNxpNciHal_setAutonomousMode()51 NFCSTATUS phNxpNciHal_setAutonomousMode() {
52   if (nfcFL.chipType != sn100u) {
53     NXPLOG_NCIHAL_D("%s : Not applicable for chipType %d", __func__,
54                     nfcFL.chipType);
55     return NFCSTATUS_SUCCESS;
56   }
57   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
58   uint8_t autonomous_mode_value = 0x01;
59   if (config_ext.autonomous_mode == true) autonomous_mode_value = 0x02;
60 
61   mEEPROM_info.request_mode = SET_EEPROM_DATA;
62   mEEPROM_info.buffer = (uint8_t*)&autonomous_mode_value;
63   mEEPROM_info.bufflen = sizeof(autonomous_mode_value);
64   mEEPROM_info.request_type = EEPROM_AUTONOMOUS_MODE;
65 
66   return request_EEPROM(&mEEPROM_info);
67 }
68 /******************************************************************************
69  * Function         phNxpNciHal_setGuardTimer
70  *
71  * Description      This function can be used to set nfcc Guard timer
72  *
73  * Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
74  *
75  ******************************************************************************/
phNxpNciHal_setGuardTimer()76 NFCSTATUS phNxpNciHal_setGuardTimer() {
77   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
78 
79   if (config_ext.autonomous_mode != true) config_ext.guard_timer_value = 0x00;
80 
81   mEEPROM_info.request_mode = SET_EEPROM_DATA;
82   mEEPROM_info.buffer = &config_ext.guard_timer_value;
83   mEEPROM_info.bufflen = sizeof(config_ext.guard_timer_value);
84   mEEPROM_info.request_type = EEPROM_GUARD_TIMER;
85 
86   return request_EEPROM(&mEEPROM_info);
87 }
88 
89 /******************************************************************************
90  * Function         get_system_property_se_type
91  *
92  * Description      This will read NFCEE status from system properties
93  *                  and returns status.
94  *
95  * Returns          NFCEE enabled(0x01)/disabled(0x00)
96  *
97  ******************************************************************************/
get_system_property_se_type(uint8_t se_type)98 static int8_t get_system_property_se_type(uint8_t se_type) {
99   int8_t retVal = -1;
100   char valueStr[PROPERTY_VALUE_MAX] = {0};
101   if (se_type >= NUM_SE_TYPES) return retVal;
102   int len = 0;
103   switch (se_type) {
104     case SE_TYPE_ESE:
105       len = property_get("nfc.product.support.ese", valueStr, "");
106       break;
107     case SE_TYPE_UICC:
108       len = property_get("nfc.product.support.uicc", valueStr, "");
109       break;
110     case SE_TYPE_UICC2:
111       len = property_get("nfc.product.support.uicc2", valueStr, "");
112       break;
113   }
114   if (strlen(valueStr) == 0 || len <= 0) {
115     return retVal;
116   }
117   retVal = atoi(valueStr);
118   return retVal;
119 }
120 
121 /******************************************************************************
122  * Function         phNxpNciHal_read_and_update_se_state
123  *
124  * Description      This will read NFCEE status from system properties
125  *                  and update to NFCC to enable/disable.
126  *
127  * Returns          none
128  *
129  ******************************************************************************/
phNxpNciHal_read_and_update_se_state()130 void phNxpNciHal_read_and_update_se_state() {
131   NFCSTATUS status = NFCSTATUS_FAILED;
132   int16_t i = 0;
133   int8_t val = -1;
134   int16_t num_se = 0;
135   uint8_t retry_cnt = 0;
136   int8_t values[NUM_SE_TYPES];
137 
138   for (i = 0; i < NUM_SE_TYPES; i++) {
139     val = get_system_property_se_type(i);
140     switch (i) {
141       case SE_TYPE_ESE:
142         NXPLOG_NCIHAL_D("Get property : SUPPORT_ESE %d", val);
143         values[SE_TYPE_ESE] = val;
144         if (val > -1) {
145           num_se++;
146         }
147         break;
148       case SE_TYPE_UICC:
149         NXPLOG_NCIHAL_D("Get property : SUPPORT_UICC %d", val);
150         values[SE_TYPE_UICC] = val;
151         if (val > -1) {
152           num_se++;
153         }
154         break;
155       case SE_TYPE_UICC2:
156         values[SE_TYPE_UICC2] = val;
157         if (val > -1) {
158           num_se++;
159         }
160         NXPLOG_NCIHAL_D("Get property : SUPPORT_UICC2 %d", val);
161         break;
162     }
163   }
164   if (num_se < 1) {
165     return;
166   }
167   uint8_t set_cfg_cmd[NCI_HEADER_SIZE + 1 +
168                       (num_se * NCI_SE_CMD_LEN)];  // 1 for Number of Argument
169   uint8_t* index = &set_cfg_cmd[0];
170   *index++ = NCI_MT_CMD;
171   *index++ = NXP_CORE_SET_CONFIG_CMD;
172   *index++ = (num_se * NCI_SE_CMD_LEN) + 1;
173   *index++ = num_se;
174   for (i = 0; i < NUM_SE_TYPES; i++) {
175     switch (i) {
176       case SE_TYPE_ESE:
177         if (values[SE_TYPE_ESE] > -1) {
178           *index++ = 0xA0;
179           *index++ = 0xED;
180           *index++ = 0x01;
181           *index++ = values[SE_TYPE_ESE];
182         }
183         break;
184       case SE_TYPE_UICC:
185         if (values[SE_TYPE_UICC] > -1) {
186           *index++ = 0xA0;
187           *index++ = 0xEC;
188           *index++ = 0x01;
189           *index++ = values[SE_TYPE_UICC];
190         }
191         break;
192       case SE_TYPE_UICC2:
193         if (values[SE_TYPE_UICC2] > -1) {
194           *index++ = 0xA0;
195           *index++ = 0xD4;
196           *index++ = 0x01;
197           *index++ = values[SE_TYPE_UICC2];
198         }
199         break;
200     }
201   }
202 
203   while (status != NFCSTATUS_SUCCESS && retry_cnt < 3) {
204     status = phNxpNciHal_send_ext_cmd(sizeof(set_cfg_cmd), set_cfg_cmd);
205     retry_cnt++;
206     NXPLOG_NCIHAL_E("Get Cfg Retry cnt=%x", retry_cnt);
207   }
208 }
209 
210 /******************************************************************************
211  * Function         phNxpNciHal_read_fw_dw_status
212  *
213  * Description      This will read the value of fw download status flag
214  *                  from eeprom
215  *
216  * Parameters       value - this parameter will be updated with the flag
217  *                  value from eeprom.
218  *
219  * Returns          status of the read
220  *
221  ******************************************************************************/
phNxpNciHal_read_fw_dw_status(uint8_t & value)222 NFCSTATUS phNxpNciHal_read_fw_dw_status(uint8_t& value) {
223   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
224   mEEPROM_info.buffer = &value;
225   mEEPROM_info.bufflen = sizeof(value);
226   mEEPROM_info.request_type = EEPROM_FW_DWNLD;
227   mEEPROM_info.request_mode = GET_EEPROM_DATA;
228   return request_EEPROM(&mEEPROM_info);
229 }
230 
231 /******************************************************************************
232  * Function         phNxpNciHal_write_fw_dw_status
233  *
234  * Description      This will update value of fw download status flag
235  *                  to eeprom
236  *
237  * Parameters       value - this value will be updated to eeprom flag.
238  *
239  * Returns          status of the write
240  *
241  ******************************************************************************/
phNxpNciHal_write_fw_dw_status(uint8_t value)242 NFCSTATUS phNxpNciHal_write_fw_dw_status(uint8_t value) {
243   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
244   mEEPROM_info.buffer = &value;
245   mEEPROM_info.bufflen = sizeof(value);
246   mEEPROM_info.request_type = EEPROM_FW_DWNLD;
247   mEEPROM_info.request_mode = SET_EEPROM_DATA;
248   return request_EEPROM(&mEEPROM_info);
249 }
250 
251 /******************************************************************************
252  * Function         phNxpNciHal_get_uicc_hci_params
253  *
254  * Description      This will read the UICC HCI param values
255  *                  from eeprom
256  *
257  * Parameters       value - this parameter will be updated with the flag
258  *                  value from eeprom.
259  *
260  * Returns          status of the read
261  *
262  ******************************************************************************/
263 NFCSTATUS
phNxpNciHal_get_uicc_hci_params(std::vector<uint8_t> & ptr,uint8_t bufflen,phNxpNci_EEPROM_request_type_t uiccType)264 phNxpNciHal_get_uicc_hci_params(std::vector<uint8_t>& ptr, uint8_t bufflen,
265                                 phNxpNci_EEPROM_request_type_t uiccType) {
266   if (nfcFL.chipType < sn220u) {
267     NXPLOG_NCIHAL_E("%s Not supported", __func__);
268     return NFCSTATUS_SUCCESS;
269   }
270   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
271   mEEPROM_info.buffer = &ptr[0];
272   mEEPROM_info.bufflen = bufflen;
273   mEEPROM_info.request_type = uiccType;
274   mEEPROM_info.request_mode = GET_EEPROM_DATA;
275   NFCSTATUS status = request_EEPROM(&mEEPROM_info);
276   ptr.resize(mEEPROM_info.bufflen);
277   return status;
278 }
279 
280 /******************************************************************************
281  * Function         phNxpNciHal_set_uicc_hci_params
282  *
283  * Description      This will update the UICC HCI param values
284  *                  to eeprom
285  *
286  * Parameters       value - this value will be updated to eeprom flag.
287  *
288  * Returns          status of the write
289  *
290  *****************************************************************************/
291 NFCSTATUS
phNxpNciHal_set_uicc_hci_params(std::vector<uint8_t> & ptr,uint8_t bufflen,phNxpNci_EEPROM_request_type_t uiccType)292 phNxpNciHal_set_uicc_hci_params(std::vector<uint8_t>& ptr, uint8_t bufflen,
293                                 phNxpNci_EEPROM_request_type_t uiccType) {
294   if (nfcFL.chipType < sn220u) {
295     NXPLOG_NCIHAL_E("%s Not supported", __func__);
296     return NFCSTATUS_SUCCESS;
297   }
298   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
299   mEEPROM_info.buffer = &ptr[0];
300   mEEPROM_info.bufflen = bufflen;
301   mEEPROM_info.request_type = uiccType;
302   mEEPROM_info.request_mode = SET_EEPROM_DATA;
303   return request_EEPROM(&mEEPROM_info);
304 }
305 
306 /*****************************************************************************
307  * Function         phNxpNciHal_send_get_cfg
308  *
309  * Description      This function is called to get the configurations from
310  * EEPROM
311  *
312  * Params           cmd_get_cfg, Buffer to get the get command
313  *                  cmd_len,     Length of the command
314  * Returns          SUCCESS/FAILURE
315  *
316  *
317  *****************************************************************************/
phNxpNciHal_send_get_cfg(const uint8_t * cmd_get_cfg,long cmd_len)318 NFCSTATUS phNxpNciHal_send_get_cfg(const uint8_t* cmd_get_cfg, long cmd_len) {
319   NXPLOG_NCIHAL_D("%s Enter", __func__);
320   NFCSTATUS status = NFCSTATUS_FAILED;
321   uint8_t retry_cnt = 0;
322 
323   if (cmd_get_cfg == NULL || cmd_len <= NCI_GET_CONFI_MIN_LEN) {
324     NXPLOG_NCIHAL_E("%s invalid command..! returning... ", __func__);
325     return status;
326   }
327 
328   do {
329     status = phNxpNciHal_send_ext_cmd(cmd_len, (uint8_t*)cmd_get_cfg);
330   } while ((status != NFCSTATUS_SUCCESS) &&
331            (retry_cnt++ < NXP_MAX_RETRY_COUNT));
332 
333   NXPLOG_NCIHAL_D("%s status : 0x%02X", __func__, status);
334   return status;
335 }
336 
337 /*****************************************************************************
338  * Function         phNxpNciHal_configure_merge_sak
339  *
340  * Description      This function is called to apply iso_dep sak merge settings
341  *                  as per the config option NAME_NXP_ISO_DEP_MERGE_SAK
342  *
343  * Params           None
344 
345  * Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
346  *
347  *****************************************************************************/
phNxpNciHal_configure_merge_sak()348 NFCSTATUS phNxpNciHal_configure_merge_sak() {
349   if (nfcFL.chipType != sn100u) {
350     NXPLOG_NCIHAL_D("%s : Not applicable for chipType %d", __func__,
351                     nfcFL.chipType);
352     return NFCSTATUS_SUCCESS;
353   }
354   long retlen = 0;
355   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
356   NXPLOG_NCIHAL_D("Performing ISODEP sak merge settings");
357   uint8_t val = 0;
358 
359   if (!GetNxpNumValue(NAME_NXP_ISO_DEP_MERGE_SAK, (void*)&retlen,
360                       sizeof(retlen))) {
361     retlen = 0x01;
362     NXPLOG_NCIHAL_D(
363         "ISO_DEP_MERGE_SAK not found. default shall be enabled : 0x%02lx",
364         retlen);
365   }
366   val = (uint8_t)retlen;
367   mEEPROM_info.buffer = &val;
368   mEEPROM_info.bufflen = sizeof(val);
369   mEEPROM_info.request_type = EEPROM_ISODEP_MERGE_SAK;
370   mEEPROM_info.request_mode = SET_EEPROM_DATA;
371   return request_EEPROM(&mEEPROM_info);
372 }
373 #if (NXP_EXTNS == TRUE && NXP_SRD == TRUE)
374 /******************************************************************************
375  * Function         phNxpNciHal_setSrdtimeout
376  *
377  * Description      This function can be used to set srd SRD Timeout.
378  *
379  * Returns          NFCSTATUS_FAILED or NFCSTATUS_SUCCESS or
380  *                  NFCSTATUS_FEATURE_NOT_SUPPORTED
381  *
382  ******************************************************************************/
phNxpNciHal_setSrdtimeout()383 NFCSTATUS phNxpNciHal_setSrdtimeout() {
384   long retlen = 0;
385   uint8_t* buffer = nullptr;
386   long bufflen = 260;
387   static const int NXP_SRD_TIMEOUT_BUF_LEN = 2;
388   static const uint16_t TIMEOUT_MASK = 0xFFFF;
389   static const uint16_t MAX_TIMEOUT_VALUE = 0x0258;
390   uint16_t isValid_timeout;
391   uint8_t timeout_buffer[NXP_SRD_TIMEOUT_BUF_LEN];
392   NFCSTATUS status = NFCSTATUS_FEATURE_NOT_SUPPORTED;
393   phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
394 
395   NXPLOG_NCIHAL_D("Performing SRD Timeout settings");
396 
397   buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t));
398   if (NULL == buffer) {
399     return NFCSTATUS_FAILED;
400   }
401   memset(buffer, 0x00, bufflen);
402   if (GetNxpByteArrayValue(NAME_NXP_SRD_TIMEOUT, (char*)buffer, bufflen,
403                            &retlen)) {
404     if (retlen == NXP_SRD_TIMEOUT_BUF_LEN) {
405       isValid_timeout = ((buffer[1] << 8) & TIMEOUT_MASK);
406       isValid_timeout = (isValid_timeout | buffer[0]);
407       if (isValid_timeout > MAX_TIMEOUT_VALUE) {
408         /*if timeout is setting more than 600 sec
409          * than setting to MAX limit 0x0258*/
410         buffer[0] = 0x58;
411         buffer[1] = 0x02;
412       }
413       memcpy(&timeout_buffer, buffer, NXP_SRD_TIMEOUT_BUF_LEN);
414       mEEPROM_info.buffer = timeout_buffer;
415       mEEPROM_info.bufflen = sizeof(timeout_buffer);
416       mEEPROM_info.request_type = EEPROM_SRD_TIMEOUT;
417       mEEPROM_info.request_mode = SET_EEPROM_DATA;
418       status = request_EEPROM(&mEEPROM_info);
419     }
420   }
421   if (buffer != NULL) {
422     free(buffer);
423     buffer = NULL;
424   }
425 
426   return status;
427 }
428 #endif
429