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