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