1 /*
2 * Copyright 2019-2021 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 #include <phNxpLog.h>
19 #include "phNfcCommon.h"
20 #include "phNxpNciHal_IoctlOperations.h"
21
22 #define NCI_HEADER_SIZE 3
23 #define NCI_SE_CMD_LEN 4
24 nxp_nfc_config_ext_t config_ext;
25 static std::vector<uint8_t> uicc1HciParams(0);
26 static std::vector<uint8_t> uicc2HciParams(0);
27 static std::vector<uint8_t> uiccHciCeParams(0);
28
29 /******************************************************************************
30 * Function phNxpNciHal_updateAutonomousPwrState
31 *
32 * Description This function can be used to update autonomous pwr state.
33 * num: value to check switch off bit is set or not.
34 *
35 * Returns uint8_t
36 *
37 ******************************************************************************/
phNxpNciHal_updateAutonomousPwrState(uint8_t num)38 uint8_t phNxpNciHal_updateAutonomousPwrState(uint8_t num) {
39 if ((config_ext.autonomous_mode == true) &&
40 ((num & SWITCH_OFF_MASK) == SWITCH_OFF_MASK)) {
41 num = (num | AUTONOMOUS_SCREEN_OFF_LOCK_MASK);
42 }
43 return num;
44 }
45 /******************************************************************************
46 * Function phNxpNciHal_setAutonomousMode
47 *
48 * Description This function can be used to set NFCC in autonomous mode
49 *
50 * Returns NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
51 * or NFCSTATUS_FEATURE_NOT_SUPPORTED
52 *
53 ******************************************************************************/
phNxpNciHal_setAutonomousMode()54 NFCSTATUS phNxpNciHal_setAutonomousMode() {
55 if (nfcFL.chipType < sn100u) {
56 NXPLOG_NCIHAL_D("%s : Not applicable for chipType %d", __func__,
57 nfcFL.chipType);
58 return NFCSTATUS_SUCCESS;
59 }
60 phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
61 uint8_t autonomous_mode_value = 0x01;
62 if (config_ext.autonomous_mode == true) autonomous_mode_value = 0x02;
63
64 mEEPROM_info.request_mode = SET_EEPROM_DATA;
65 mEEPROM_info.buffer = (uint8_t*)&autonomous_mode_value;
66 mEEPROM_info.bufflen = sizeof(autonomous_mode_value);
67 mEEPROM_info.request_type = EEPROM_AUTONOMOUS_MODE;
68
69 return request_EEPROM(&mEEPROM_info);
70 }
71 /******************************************************************************
72 * Function phNxpNciHal_setGuardTimer
73 *
74 * Description This function can be used to set nfcc Guard timer
75 *
76 * Returns NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
77 *
78 ******************************************************************************/
phNxpNciHal_setGuardTimer()79 NFCSTATUS phNxpNciHal_setGuardTimer() {
80 phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
81 NFCSTATUS status = NFCSTATUS_FEATURE_NOT_SUPPORTED;
82
83 if (nfcFL.chipType >= sn100u) {
84 if (config_ext.autonomous_mode != true) config_ext.guard_timer_value = 0x00;
85
86 mEEPROM_info.request_mode = SET_EEPROM_DATA;
87 mEEPROM_info.buffer = &config_ext.guard_timer_value;
88 mEEPROM_info.bufflen = sizeof(config_ext.guard_timer_value);
89 mEEPROM_info.request_type = EEPROM_GUARD_TIMER;
90
91 status = request_EEPROM(&mEEPROM_info);
92 }
93 return status;
94 }
95
96 /******************************************************************************
97 * Function get_system_property_se_type
98 *
99 * Description This will read NFCEE status from system properties
100 * and returns status.
101 *
102 * Returns NFCEE enabled(0x01)/disabled(0x00)
103 *
104 ******************************************************************************/
get_system_property_se_type(uint8_t se_type)105 static int8_t get_system_property_se_type(uint8_t se_type) {
106 int8_t retVal = -1;
107 char valueStr[PROPERTY_VALUE_MAX] = {0};
108 if (se_type >= NUM_SE_TYPES) return retVal;
109 int len = 0;
110 switch (se_type) {
111 case SE_TYPE_ESE:
112 len = property_get("nfc.product.support.ese", valueStr, "");
113 break;
114 case SE_TYPE_UICC:
115 len = property_get("nfc.product.support.uicc", valueStr, "");
116 break;
117 case SE_TYPE_UICC2:
118 len = property_get("nfc.product.support.uicc2", valueStr, "");
119 break;
120 }
121 if (strlen(valueStr) == 0 || len <= 0) {
122 return retVal;
123 }
124 retVal = atoi(valueStr);
125 return retVal;
126 }
127
128 /******************************************************************************
129 * Function phNxpNciHal_read_and_update_se_state
130 *
131 * Description This will read NFCEE status from system properties
132 * and update to NFCC to enable/disable.
133 *
134 * Returns none
135 *
136 ******************************************************************************/
phNxpNciHal_read_and_update_se_state()137 void phNxpNciHal_read_and_update_se_state() {
138 NFCSTATUS status = NFCSTATUS_FAILED;
139 int16_t i = 0;
140 int8_t val = -1;
141 int16_t num_se = 0;
142 uint8_t retry_cnt = 0;
143 int8_t values[NUM_SE_TYPES];
144
145 for (i = 0; i < NUM_SE_TYPES; i++) {
146 val = get_system_property_se_type(i);
147 switch (i) {
148 case SE_TYPE_ESE:
149 NXPLOG_NCIHAL_D("Get property : SUPPORT_ESE %d", val);
150 values[SE_TYPE_ESE] = val;
151 if (val > -1) {
152 num_se++;
153 }
154 break;
155 case SE_TYPE_UICC:
156 NXPLOG_NCIHAL_D("Get property : SUPPORT_UICC %d", val);
157 values[SE_TYPE_UICC] = val;
158 if (val > -1) {
159 num_se++;
160 }
161 break;
162 case SE_TYPE_UICC2:
163 values[SE_TYPE_UICC2] = val;
164 if (val > -1) {
165 num_se++;
166 }
167 NXPLOG_NCIHAL_D("Get property : SUPPORT_UICC2 %d", val);
168 break;
169 }
170 }
171 if (num_se < 1) {
172 return;
173 }
174 uint8_t set_cfg_cmd[NCI_HEADER_SIZE + 1 +
175 (num_se * NCI_SE_CMD_LEN)]; // 1 for Number of Argument
176 uint8_t* index = &set_cfg_cmd[0];
177 *index++ = NCI_MT_CMD;
178 *index++ = NXP_CORE_SET_CONFIG_CMD;
179 *index++ = (num_se * NCI_SE_CMD_LEN) + 1;
180 *index++ = num_se;
181 for (i = 0; i < NUM_SE_TYPES; i++) {
182 switch (i) {
183 case SE_TYPE_ESE:
184 if (values[SE_TYPE_ESE] > -1) {
185 *index++ = 0xA0;
186 *index++ = 0xED;
187 *index++ = 0x01;
188 *index++ = values[SE_TYPE_ESE];
189 }
190 break;
191 case SE_TYPE_UICC:
192 if (values[SE_TYPE_UICC] > -1) {
193 *index++ = 0xA0;
194 *index++ = 0xEC;
195 *index++ = 0x01;
196 *index++ = values[SE_TYPE_UICC];
197 }
198 break;
199 case SE_TYPE_UICC2:
200 if (values[SE_TYPE_UICC2] > -1) {
201 *index++ = 0xA0;
202 *index++ = 0xD4;
203 *index++ = 0x01;
204 *index++ = values[SE_TYPE_UICC2];
205 }
206 break;
207 }
208 }
209
210 while (status != NFCSTATUS_SUCCESS && retry_cnt < 3) {
211 status = phNxpNciHal_send_ext_cmd(sizeof(set_cfg_cmd), set_cfg_cmd);
212 retry_cnt++;
213 NXPLOG_NCIHAL_E("Get Cfg Retry cnt=%x", retry_cnt);
214 }
215 }
216
217 /******************************************************************************
218 * Function phNxpNciHal_read_fw_dw_status
219 *
220 * Description This will read the value of fw download status flag
221 * from eeprom
222 *
223 * Parameters value - this parameter will be updated with the flag
224 * value from eeprom.
225 *
226 * Returns status of the read
227 *
228 ******************************************************************************/
phNxpNciHal_read_fw_dw_status(uint8_t & value)229 NFCSTATUS phNxpNciHal_read_fw_dw_status(uint8_t& value) {
230 phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
231 mEEPROM_info.buffer = &value;
232 mEEPROM_info.bufflen = sizeof(value);
233 mEEPROM_info.request_type = EEPROM_FW_DWNLD;
234 mEEPROM_info.request_mode = GET_EEPROM_DATA;
235 return request_EEPROM(&mEEPROM_info);
236 }
237
238 /******************************************************************************
239 * Function phNxpNciHal_write_fw_dw_status
240 *
241 * Description This will update value of fw download status flag
242 * to eeprom
243 *
244 * Parameters value - this value will be updated to eeprom flag.
245 *
246 * Returns status of the write
247 *
248 ******************************************************************************/
phNxpNciHal_write_fw_dw_status(uint8_t value)249 NFCSTATUS phNxpNciHal_write_fw_dw_status(uint8_t value) {
250 phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
251 mEEPROM_info.buffer = &value;
252 mEEPROM_info.bufflen = sizeof(value);
253 mEEPROM_info.request_type = EEPROM_FW_DWNLD;
254 mEEPROM_info.request_mode = SET_EEPROM_DATA;
255 return request_EEPROM(&mEEPROM_info);
256 }
257
258 /******************************************************************************
259 * Function phNxpNciHal_save_uicc_params
260 *
261 * Description This will read the UICC HCI param values
262 * from eeprom and store in global variable
263 *
264 * Returns status of the read
265 *
266 ******************************************************************************/
phNxpNciHal_save_uicc_params()267 NFCSTATUS phNxpNciHal_save_uicc_params() {
268 if (nfcFL.chipType < sn220u) {
269 NXPLOG_NCIHAL_E("%s Not supported", __func__);
270 return NFCSTATUS_SUCCESS;
271 }
272
273 NFCSTATUS status = NFCSTATUS_FAILED;
274
275 /* Getting UICC2 CL params */
276 uicc1HciParams.resize(0xFF);
277 status = phNxpNciHal_get_uicc_hci_params(
278 uicc1HciParams, uicc1HciParams.size(), EEPROM_UICC1_SESSION_ID);
279 if (status != NFCSTATUS_SUCCESS) {
280 NXPLOG_NCIHAL_E("%s: Save UICC1 CLPP failed .", __func__);
281 }
282
283 /* Getting UICC2 CL params */
284 uicc2HciParams.resize(0xFF);
285 status = phNxpNciHal_get_uicc_hci_params(
286 uicc2HciParams, uicc2HciParams.size(), EEPROM_UICC2_SESSION_ID);
287 if (status != NFCSTATUS_SUCCESS) {
288 NXPLOG_NCIHAL_E("%s: Save UICC2 CLPP failed .", __func__);
289 }
290
291 /* Get UICC CE HCI State */
292 uiccHciCeParams.resize(0xFF);
293 status = phNxpNciHal_get_uicc_hci_params(
294 uiccHciCeParams, uiccHciCeParams.size(), EEPROM_UICC_HCI_CE_STATE);
295 if (status != NFCSTATUS_SUCCESS) {
296 NXPLOG_NCIHAL_E("%s: Save UICC_HCI_CE_STATE failed .", __func__);
297 }
298 return status;
299 }
300
301 /******************************************************************************
302 * Function phNxpNciHal_restore_uicc_params
303 *
304 * Description This will set the UICC HCI param values
305 * back to eeprom from global variable
306 *
307 * Returns status of the read
308 *
309 ******************************************************************************/
phNxpNciHal_restore_uicc_params()310 NFCSTATUS phNxpNciHal_restore_uicc_params() {
311 if (nfcFL.chipType < sn220u) {
312 NXPLOG_NCIHAL_E("%s Not supported", __func__);
313 return NFCSTATUS_SUCCESS;
314 }
315
316 NFCSTATUS status = NFCSTATUS_FAILED;
317 if (uicc1HciParams.size() > 0) {
318 status = phNxpNciHal_set_uicc_hci_params(
319 uicc1HciParams, uicc1HciParams.size(), EEPROM_UICC1_SESSION_ID);
320 if (status != NFCSTATUS_SUCCESS) {
321 NXPLOG_NCIHAL_E("%s: Restore UICC1 CLPP failed .", __func__);
322 } else {
323 uicc1HciParams.resize(0);
324 }
325 }
326 if (uicc2HciParams.size() > 0) {
327 status = phNxpNciHal_set_uicc_hci_params(
328 uicc2HciParams, uicc2HciParams.size(), EEPROM_UICC2_SESSION_ID);
329 if (status != NFCSTATUS_SUCCESS) {
330 NXPLOG_NCIHAL_E("%s: Restore UICC2 CLPP failed .", __func__);
331 } else {
332 uicc2HciParams.resize(0);
333 }
334 }
335 if (uiccHciCeParams.size() > 0) {
336 status = phNxpNciHal_set_uicc_hci_params(
337 uiccHciCeParams, uiccHciCeParams.size(), EEPROM_UICC_HCI_CE_STATE);
338 if (status != NFCSTATUS_SUCCESS) {
339 NXPLOG_NCIHAL_E("%s: Restore UICC_HCI_CE_STATE failed .", __func__);
340 } else {
341 uiccHciCeParams.resize(0);
342 }
343 }
344 return status;
345 }
346
347 /******************************************************************************
348 * Function phNxpNciHal_get_uicc_hci_params
349 *
350 * Description This will read the UICC HCI param values
351 * from eeprom
352 *
353 * Parameters value - this parameter will be updated with the flag
354 * value from eeprom.
355 *
356 * Returns status of the read
357 *
358 ******************************************************************************/
359 NFCSTATUS
phNxpNciHal_get_uicc_hci_params(std::vector<uint8_t> & ptr,uint8_t bufflen,phNxpNci_EEPROM_request_type_t uiccType)360 phNxpNciHal_get_uicc_hci_params(std::vector<uint8_t>& ptr, uint8_t bufflen,
361 phNxpNci_EEPROM_request_type_t uiccType) {
362 if (nfcFL.chipType < sn220u) {
363 NXPLOG_NCIHAL_E("%s Not supported", __func__);
364 return NFCSTATUS_SUCCESS;
365 }
366 phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
367 mEEPROM_info.buffer = &ptr[0];
368 mEEPROM_info.bufflen = bufflen;
369 mEEPROM_info.request_type = uiccType;
370 mEEPROM_info.request_mode = GET_EEPROM_DATA;
371 NFCSTATUS status = request_EEPROM(&mEEPROM_info);
372 ptr.resize(mEEPROM_info.bufflen);
373 return status;
374 }
375
376 /******************************************************************************
377 * Function phNxpNciHal_set_uicc_hci_params
378 *
379 * Description This will update the UICC HCI param values
380 * to eeprom
381 *
382 * Parameters value - this value will be updated to eeprom flag.
383 *
384 * Returns status of the write
385 *
386 *****************************************************************************/
387 NFCSTATUS
phNxpNciHal_set_uicc_hci_params(std::vector<uint8_t> & ptr,uint8_t bufflen,phNxpNci_EEPROM_request_type_t uiccType)388 phNxpNciHal_set_uicc_hci_params(std::vector<uint8_t>& ptr, uint8_t bufflen,
389 phNxpNci_EEPROM_request_type_t uiccType) {
390 if (nfcFL.chipType < sn220u) {
391 NXPLOG_NCIHAL_E("%s Not supported", __func__);
392 return NFCSTATUS_SUCCESS;
393 }
394 phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
395 mEEPROM_info.buffer = &ptr[0];
396 mEEPROM_info.bufflen = bufflen;
397 mEEPROM_info.request_type = uiccType;
398 mEEPROM_info.request_mode = SET_EEPROM_DATA;
399 return request_EEPROM(&mEEPROM_info);
400 }
401
402 /*****************************************************************************
403 * Function phNxpNciHal_send_get_cfg
404 *
405 * Description This function is called to get the configurations from
406 * EEPROM
407 *
408 * Params cmd_get_cfg, Buffer to get the get command
409 * cmd_len, Length of the command
410 * Returns SUCCESS/FAILURE
411 *
412 *
413 *****************************************************************************/
phNxpNciHal_send_get_cfg(const uint8_t * cmd_get_cfg,long cmd_len)414 NFCSTATUS phNxpNciHal_send_get_cfg(const uint8_t* cmd_get_cfg, long cmd_len) {
415 NXPLOG_NCIHAL_D("%s Enter", __func__);
416 NFCSTATUS status = NFCSTATUS_FAILED;
417 uint8_t retry_cnt = 0;
418
419 if (cmd_get_cfg == NULL || cmd_len <= NCI_GET_CONFI_MIN_LEN) {
420 NXPLOG_NCIHAL_E("%s invalid command..! returning... ", __func__);
421 return status;
422 }
423
424 do {
425 status = phNxpNciHal_send_ext_cmd(cmd_len, (uint8_t*)cmd_get_cfg);
426 } while ((status != NFCSTATUS_SUCCESS) &&
427 (retry_cnt++ < NXP_MAX_RETRY_COUNT));
428
429 NXPLOG_NCIHAL_D("%s status : 0x%02X", __func__, status);
430 return status;
431 }
432
433 /*****************************************************************************
434 * Function phNxpNciHal_configure_merge_sak
435 *
436 * Description This function is called to apply iso_dep sak merge settings
437 * as per the config option NAME_NXP_ISO_DEP_MERGE_SAK
438 *
439 * Params None
440
441 * Returns NFCSTATUS_FAILED or NFCSTATUS_SUCCESS
442 *
443 *****************************************************************************/
phNxpNciHal_configure_merge_sak()444 NFCSTATUS phNxpNciHal_configure_merge_sak() {
445 if (nfcFL.chipType < sn100u) {
446 NXPLOG_NCIHAL_D("%s : Not applicable for chipType %d", __func__,
447 nfcFL.chipType);
448 return NFCSTATUS_SUCCESS;
449 }
450 long retlen = 0;
451 phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
452 NXPLOG_NCIHAL_D("Performing ISODEP sak merge settings");
453 uint8_t val = 0;
454
455 if (!GetNxpNumValue(NAME_NXP_ISO_DEP_MERGE_SAK, (void*)&retlen,
456 sizeof(retlen))) {
457 retlen = 0x01;
458 NXPLOG_NCIHAL_D(
459 "ISO_DEP_MERGE_SAK not found. default shall be enabled : 0x%02lx",
460 retlen);
461 }
462 val = (uint8_t)retlen;
463 mEEPROM_info.buffer = &val;
464 mEEPROM_info.bufflen = sizeof(val);
465 mEEPROM_info.request_type = EEPROM_ISODEP_MERGE_SAK;
466 mEEPROM_info.request_mode = SET_EEPROM_DATA;
467 return request_EEPROM(&mEEPROM_info);
468 }
469 #if (NXP_EXTNS == TRUE && NXP_SRD == TRUE)
470 /******************************************************************************
471 * Function phNxpNciHal_setSrdtimeout
472 *
473 * Description This function can be used to set srd SRD Timeout.
474 *
475 * Returns NFCSTATUS_FAILED or NFCSTATUS_SUCCESS or
476 * NFCSTATUS_FEATURE_NOT_SUPPORTED
477 *
478 ******************************************************************************/
phNxpNciHal_setSrdtimeout()479 NFCSTATUS phNxpNciHal_setSrdtimeout() {
480 long retlen = 0;
481 uint8_t* buffer = nullptr;
482 long bufflen = 260;
483 const int NXP_SRD_TIMEOUT_BUF_LEN = 2;
484 const uint16_t TIMEOUT_MASK = 0xFFFF;
485 const uint16_t MAX_TIMEOUT_VALUE = 0xFD70;
486 uint16_t isValid_timeout;
487 uint8_t timeout_buffer[NXP_SRD_TIMEOUT_BUF_LEN];
488 NFCSTATUS status = NFCSTATUS_FEATURE_NOT_SUPPORTED;
489 phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
490
491 NXPLOG_NCIHAL_D("Performing SRD Timeout settings");
492
493 buffer = (uint8_t*)malloc(bufflen * sizeof(uint8_t));
494 if (NULL == buffer) {
495 return NFCSTATUS_FAILED;
496 }
497 memset(buffer, 0x00, bufflen);
498 if (GetNxpByteArrayValue(NAME_NXP_SRD_TIMEOUT, (char*)buffer, bufflen,
499 &retlen)) {
500 if (retlen == NXP_SRD_TIMEOUT_BUF_LEN) {
501 isValid_timeout = ((buffer[1] << 8) & TIMEOUT_MASK);
502 isValid_timeout = (isValid_timeout | buffer[0]);
503 if (isValid_timeout > MAX_TIMEOUT_VALUE) {
504 /*if timeout is setting more than 18hrs
505 * than setting to MAX limit 0xFD70*/
506 buffer[0] = 0x70;
507 buffer[1] = 0xFD;
508 }
509 memcpy(&timeout_buffer, buffer, NXP_SRD_TIMEOUT_BUF_LEN);
510 mEEPROM_info.buffer = timeout_buffer;
511 mEEPROM_info.bufflen = sizeof(timeout_buffer);
512 mEEPROM_info.request_type = EEPROM_SRD_TIMEOUT;
513 mEEPROM_info.request_mode = SET_EEPROM_DATA;
514 status = request_EEPROM(&mEEPROM_info);
515 }
516 }
517 if (buffer != NULL) {
518 free(buffer);
519 buffer = NULL;
520 }
521
522 return status;
523 }
524 #endif
525
526 /******************************************************************************
527 * Function phNxpNciHal_setExtendedFieldMode
528 *
529 * Description This function can be used to set nfcc extended field mode
530 *
531 * Returns NFCSTATUS_FAILED or NFCSTATUS_SUCCESS or
532 * NFCSTATUS_FEATURE_NOT_SUPPORTED
533 *
534 ******************************************************************************/
phNxpNciHal_setExtendedFieldMode()535 NFCSTATUS phNxpNciHal_setExtendedFieldMode() {
536 const uint8_t enable_val = 0x01;
537 const uint8_t disable_val = 0x00;
538 uint8_t extended_field_mode = disable_val;
539 phNxpNci_EEPROM_info_t mEEPROM_info = {.request_mode = 0};
540 NFCSTATUS status = NFCSTATUS_FEATURE_NOT_SUPPORTED;
541
542 if (nfcFL.chipType >= sn100u &&
543 GetNxpNumValue(NAME_NXP_EXTENDED_FIELD_DETECT_MODE, &extended_field_mode,
544 sizeof(extended_field_mode))) {
545 if (extended_field_mode == enable_val ||
546 extended_field_mode == disable_val) {
547 mEEPROM_info.buffer = &extended_field_mode;
548 mEEPROM_info.bufflen = sizeof(extended_field_mode);
549 mEEPROM_info.request_type = EEPROM_EXT_FIELD_DETECT_MODE;
550 mEEPROM_info.request_mode = SET_EEPROM_DATA;
551 status = request_EEPROM(&mEEPROM_info);
552 } else {
553 NXPLOG_NCIHAL_E("Invalid Extended Field Mode in config");
554 }
555 }
556 return status;
557 }
558