1 /******************************************************************************
2 *
3 * Copyright (C) 1999-2012 Broadcom Corporation
4 * Copyright (C) 2013 ST Microelectronics S.A.
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 * Modified by ST Microelectronics S.A. (adaptation of nfc_nci.c for ST21NFC
19 *NCI version)
20 *
21 ******************************************************************************/
22
23 #include <android-base/properties.h>
24 #include <dlfcn.h>
25 #include <errno.h>
26 #include <string.h>
27
28 #include "StNfc_hal_api.h"
29 #include "android_logmsg.h"
30 #include "hal_config.h"
31 #include "halcore.h"
32 #include "st21nfc_dev.h"
33 #include "hal_fd.h"
34
35 #if defined(ST_LIB_32)
36 #define VENDOR_LIB_PATH "/vendor/lib/"
37 #else
38 #define VENDOR_LIB_PATH "/vendor/lib64/"
39 #endif
40 #define VENDOR_LIB_EXT ".so"
41
42 bool dbg_logging = false;
43
44 extern void HalCoreCallback(void* context, uint32_t event, const void* d,
45 size_t length);
46 extern bool I2cOpenLayer(void* dev, HAL_CALLBACK callb, HALHANDLE* pHandle);
47
48 typedef int (*STEseReset)(void);
49
50 const char* halVersion = "ST21NFC AIDL Version 1.0.0";
51
52 uint8_t cmd_set_nfc_mode_enable[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
53 uint8_t hal_is_closed = 1;
54 pthread_mutex_t hal_mtx = PTHREAD_MUTEX_INITIALIZER;
55 st21nfc_dev_t dev;
56 int nfc_mode = 0;
57
58 /*
59 * NCI HAL method implementations. These must be overridden
60 */
61
62 extern bool hal_wrapper_open(st21nfc_dev_t* dev, nfc_stack_callback_t* p_cback,
63 nfc_stack_data_callback_t* p_data_cback,
64 HALHANDLE* pHandle);
65
66 extern int hal_wrapper_close(int call_cb, int nfc_mode);
67
68 extern void hal_wrapper_send_config();
69 extern void hal_wrapper_factoryReset();
70 extern void hal_wrapper_set_observer_mode(uint8_t enable);
71 extern void hal_wrapper_get_observer_mode();
72
73 /* Make sure to always post nfc_stack_callback_t in a separate thread.
74 This prevents a possible deadlock in upper layer on some sequences.
75 We need to synchronize finely for the callback called for hal close,
76 otherwise the upper layer either does not receive the event, or deadlocks,
77 because the HAL is closing while the callback may be blocked.
78 */
79 static struct async_callback_struct {
80 pthread_mutex_t mutex;
81 pthread_cond_t cond;
82 pthread_t thr;
83 int event_pending;
84 int stop_thread;
85 int thread_running;
86 nfc_event_t event;
87 nfc_status_t event_status;
88 } async_callback_data;
89
async_callback_thread_fct(void * arg)90 static void* async_callback_thread_fct(void* arg) {
91 int ret;
92 struct async_callback_struct* pcb_data = (struct async_callback_struct*)arg;
93
94 ret = pthread_mutex_lock(&pcb_data->mutex);
95 if (ret != 0) {
96 STLOG_HAL_E("HAL: %s pthread_mutex_lock failed", __func__);
97 goto error;
98 }
99
100 do {
101 if (pcb_data->event_pending == 0) {
102 ret = pthread_cond_wait(&pcb_data->cond, &pcb_data->mutex);
103 if (ret != 0) {
104 STLOG_HAL_E("HAL: %s pthread_cond_wait failed", __func__);
105 break;
106 }
107 }
108
109 if (pcb_data->event_pending) {
110 nfc_event_t event = pcb_data->event;
111 nfc_status_t event_status = pcb_data->event_status;
112 int ending = pcb_data->stop_thread;
113 pcb_data->event_pending = 0;
114 ret = pthread_cond_signal(&pcb_data->cond);
115 if (ret != 0) {
116 STLOG_HAL_E("HAL: %s pthread_cond_signal failed", __func__);
117 break;
118 }
119 if (ending) {
120 pcb_data->thread_running = 0;
121 }
122 ret = pthread_mutex_unlock(&pcb_data->mutex);
123 if (ret != 0) {
124 STLOG_HAL_E("HAL: %s pthread_mutex_unlock failed", __func__);
125 }
126 STLOG_HAL_D("HAL st21nfc: %s event %hhx status %hhx", __func__, event,
127 event_status);
128 dev.p_cback_unwrap(event, event_status);
129 if (ending) {
130 return NULL;
131 }
132 ret = pthread_mutex_lock(&pcb_data->mutex);
133 if (ret != 0) {
134 STLOG_HAL_E("HAL: %s pthread_mutex_lock failed", __func__);
135 goto error;
136 }
137 }
138 } while (pcb_data->stop_thread == 0 || pcb_data->event_pending);
139
140 ret = pthread_mutex_unlock(&pcb_data->mutex);
141 if (ret != 0) {
142 STLOG_HAL_E("HAL: %s pthread_mutex_unlock failed", __func__);
143 }
144
145 error:
146 pcb_data->thread_running = 0;
147 return NULL;
148 }
149
async_callback_thread_start()150 static int async_callback_thread_start() {
151 int ret;
152
153 memset(&async_callback_data, 0, sizeof(async_callback_data));
154
155 ret = pthread_mutex_init(&async_callback_data.mutex, NULL);
156 if (ret != 0) {
157 STLOG_HAL_E("HAL: %s pthread_mutex_init failed", __func__);
158 return ret;
159 }
160
161 ret = pthread_cond_init(&async_callback_data.cond, NULL);
162 if (ret != 0) {
163 STLOG_HAL_E("HAL: %s pthread_cond_init failed", __func__);
164 return ret;
165 }
166
167 async_callback_data.thread_running = 1;
168
169 ret = pthread_create(&async_callback_data.thr, NULL,
170 async_callback_thread_fct, &async_callback_data);
171 if (ret != 0) {
172 STLOG_HAL_E("HAL: %s pthread_create failed", __func__);
173 async_callback_data.thread_running = 0;
174 return ret;
175 }
176
177 return 0;
178 }
179
async_callback_thread_end()180 static int async_callback_thread_end() {
181 if (async_callback_data.thread_running != 0) {
182 int ret;
183
184 ret = pthread_mutex_lock(&async_callback_data.mutex);
185 if (ret != 0) {
186 STLOG_HAL_E("HAL: %s pthread_mutex_lock failed", __func__);
187 return ret;
188 }
189
190 async_callback_data.stop_thread = 1;
191
192 // Wait for the thread to have no event pending
193 while (async_callback_data.thread_running &&
194 async_callback_data.event_pending) {
195 ret = pthread_cond_signal(&async_callback_data.cond);
196 if (ret != 0) {
197 STLOG_HAL_E("HAL: %s pthread_cond_signal failed", __func__);
198 return ret;
199 }
200 ret = pthread_cond_wait(&async_callback_data.cond,
201 &async_callback_data.mutex);
202 if (ret != 0) {
203 STLOG_HAL_E("HAL: %s pthread_cond_wait failed", __func__);
204 break;
205 }
206 }
207
208 ret = pthread_mutex_unlock(&async_callback_data.mutex);
209 if (ret != 0) {
210 STLOG_HAL_E("HAL: %s pthread_mutex_unlock failed", __func__);
211 return ret;
212 }
213
214 ret = pthread_cond_signal(&async_callback_data.cond);
215 if (ret != 0) {
216 STLOG_HAL_E("HAL: %s pthread_cond_signal failed", __func__);
217 return ret;
218 }
219
220 ret = pthread_join(async_callback_data.thr, (void**)NULL);
221 if (ret != 0) {
222 STLOG_HAL_E("HAL: %s pthread_join failed", __func__);
223 return ret;
224 }
225 }
226 return 0;
227 }
228
async_callback_post(nfc_event_t event,nfc_status_t event_status)229 static void async_callback_post(nfc_event_t event, nfc_status_t event_status) {
230 int ret;
231
232 if (pthread_equal(pthread_self(), async_callback_data.thr)) {
233 dev.p_cback_unwrap(event, event_status);
234 }
235
236 ret = pthread_mutex_lock(&async_callback_data.mutex);
237 if (ret != 0) {
238 STLOG_HAL_E("HAL: %s pthread_mutex_lock failed", __func__);
239 return;
240 }
241
242 if (async_callback_data.thread_running == 0) {
243 (void)pthread_mutex_unlock(&async_callback_data.mutex);
244 STLOG_HAL_E("HAL: %s thread is not running", __func__);
245 dev.p_cback_unwrap(event, event_status);
246 return;
247 }
248
249 while (async_callback_data.event_pending) {
250 ret = pthread_cond_wait(&async_callback_data.cond,
251 &async_callback_data.mutex);
252 if (ret != 0) {
253 STLOG_HAL_E("HAL: %s pthread_cond_wait failed", __func__);
254 return;
255 }
256 }
257
258 async_callback_data.event_pending = 1;
259 async_callback_data.event = event;
260 async_callback_data.event_status = event_status;
261
262 ret = pthread_mutex_unlock(&async_callback_data.mutex);
263 if (ret != 0) {
264 STLOG_HAL_E("HAL: %s pthread_mutex_unlock failed", __func__);
265 return;
266 }
267
268 ret = pthread_cond_signal(&async_callback_data.cond);
269 if (ret != 0) {
270 STLOG_HAL_E("HAL: %s pthread_cond_signal failed", __func__);
271 return;
272 }
273 }
274 /* ------ */
275
StNfc_hal_open(nfc_stack_callback_t * p_cback,nfc_stack_data_callback_t * p_data_cback)276 int StNfc_hal_open(nfc_stack_callback_t* p_cback,
277 nfc_stack_data_callback_t* p_data_cback) {
278 bool result = false;
279
280 STLOG_HAL_D("HAL st21nfc: %s %s", __func__, halVersion);
281
282 (void)pthread_mutex_lock(&hal_mtx);
283
284 if (!hal_is_closed) {
285 hal_wrapper_close(0, nfc_mode);
286 }
287
288 dev.p_cback = p_cback; // will be replaced by wrapper version
289 dev.p_cback_unwrap = p_cback;
290 dev.p_data_cback = p_data_cback;
291 // Initialize and get global logging level
292 InitializeSTLogLevel();
293
294 if ((hal_is_closed || !async_callback_data.thread_running) &&
295 (async_callback_thread_start() != 0)) {
296 dev.p_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
297 (void)pthread_mutex_unlock(&hal_mtx);
298 return -1; // We are doomed, stop it here, NOW !
299 }
300 result =
301 hal_wrapper_open(&dev, async_callback_post, p_data_cback, &(dev.hHAL));
302
303 if (!result || !(dev.hHAL)) {
304 async_callback_post(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
305 (void)pthread_mutex_unlock(&hal_mtx);
306 return -1; // We are doomed, stop it here, NOW !
307 }
308 hal_is_closed = 0;
309 (void)pthread_mutex_unlock(&hal_mtx);
310 return 0;
311 }
312
StNfc_hal_write(uint16_t data_len,const uint8_t * p_data)313 int StNfc_hal_write(uint16_t data_len, const uint8_t* p_data) {
314 STLOG_HAL_D("HAL st21nfc: %s", __func__);
315
316 uint8_t NCI_ANDROID_PASSIVE_OBSERVER_PREFIX[] = {0x2f, 0x0c, 0x02, 0x02};
317 uint8_t NCI_QUERY_ANDROID_PASSIVE_OBSERVER_PREFIX[] = {0x2f, 0x0c, 0x01, 0x4};
318 uint8_t RF_GET_LISTEN_OBSERVE_MODE_STATE[5] = {0x21, 0x17, 0x00};
319 uint8_t RF_SET_LISTEN_OBSERVE_MODE_STATE[4] = {0x21, 0x16, 0x01, 0x0};
320 uint8_t CORE_GET_CONFIG_OBSERVER[5] = {0x20, 0x03, 0x02, 0x01, 0xa3};
321 uint8_t CORE_SET_CONFIG_OBSERVER[7] = {0x20, 0x02, 0x04, 0x01,
322 0xa3, 0x01, 0x00};
323 uint8_t* mGetObserve = CORE_GET_CONFIG_OBSERVER;
324 uint8_t mGetObserve_size = 5;
325 uint8_t* mSetObserve = CORE_SET_CONFIG_OBSERVER;
326 uint8_t mSetObserve_size = 7;
327 uint8_t mTechObserved = 0x0;
328 /* check if HAL is closed */
329 int ret = (int)data_len;
330 (void)pthread_mutex_lock(&hal_mtx);
331 if (hal_is_closed) {
332 ret = 0;
333 }
334
335 if (!ret) {
336 (void)pthread_mutex_unlock(&hal_mtx);
337 return ret;
338 }
339
340 if (data_len == 4 &&
341 !memcmp(p_data, NCI_QUERY_ANDROID_PASSIVE_OBSERVER_PREFIX,
342 sizeof(NCI_QUERY_ANDROID_PASSIVE_OBSERVER_PREFIX))) {
343 hal_wrapper_get_observer_mode();
344 if (hal_fd_getFwCap()->ObserveMode == 2) {
345 mGetObserve = RF_GET_LISTEN_OBSERVE_MODE_STATE;
346 mGetObserve_size = 3;
347 }
348 if (!HalSendDownstream(dev.hHAL, mGetObserve, mGetObserve_size)) {
349 STLOG_HAL_E("HAL st21nfc %s SendDownstream failed", __func__);
350 (void)pthread_mutex_unlock(&hal_mtx);
351 return 0;
352 }
353 }
354
355 else if (data_len == 5 &&
356 !memcmp(p_data, NCI_ANDROID_PASSIVE_OBSERVER_PREFIX,
357 sizeof(NCI_ANDROID_PASSIVE_OBSERVER_PREFIX))) {
358 if (hal_fd_getFwCap()->ObserveMode == 2) {
359 mSetObserve = RF_SET_LISTEN_OBSERVE_MODE_STATE;
360 mSetObserve_size = 4;
361 if (p_data[4]) {
362 mTechObserved = 0x7;
363 }
364 mSetObserve[3] = mTechObserved;
365 hal_wrapper_set_observer_mode(mTechObserved);
366 } else {
367 mSetObserve[6] = p_data[4];
368 hal_wrapper_set_observer_mode(p_data[4]);
369 }
370
371 if (!HalSendDownstream(dev.hHAL, mSetObserve, mSetObserve_size)) {
372 STLOG_HAL_E("HAL st21nfc %s SendDownstream failed", __func__);
373 (void)pthread_mutex_unlock(&hal_mtx);
374 return 0;
375 }
376 } else if (!HalSendDownstream(dev.hHAL, p_data, data_len)) {
377 STLOG_HAL_E("HAL st21nfc %s SendDownstream failed", __func__);
378 (void)pthread_mutex_unlock(&hal_mtx);
379 return 0;
380 }
381 (void)pthread_mutex_unlock(&hal_mtx);
382
383 return ret;
384 }
385
StNfc_hal_core_initialized()386 int StNfc_hal_core_initialized() {
387 STLOG_HAL_D("HAL st21nfc: %s", __func__);
388
389 (void)pthread_mutex_lock(&hal_mtx);
390 hal_wrapper_send_config();
391 (void)pthread_mutex_unlock(&hal_mtx);
392
393 return 0; // return != 0 to signal ready immediate
394 }
395
StNfc_hal_pre_discover()396 int StNfc_hal_pre_discover() {
397 STLOG_HAL_D("HAL st21nfc: %s", __func__);
398 async_callback_post(HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
399 // callback directly if no vendor-specific pre-discovery actions are needed
400 return 0;
401 }
402
StNfc_hal_close(int nfc_mode_value)403 int StNfc_hal_close(int nfc_mode_value) {
404 void* stdll = nullptr;
405 STLOG_HAL_D("HAL st21nfc: %s nfc_mode = %d", __func__, nfc_mode_value);
406
407 /* check if HAL is closed */
408 (void)pthread_mutex_lock(&hal_mtx);
409 if (hal_is_closed) {
410 (void)pthread_mutex_unlock(&hal_mtx);
411 return 1;
412 }
413 if (hal_wrapper_close(1, nfc_mode_value) == -1) {
414 hal_is_closed = 1;
415 (void)pthread_mutex_unlock(&hal_mtx);
416 return 1;
417 }
418 hal_is_closed = 1;
419 (void)pthread_mutex_unlock(&hal_mtx);
420
421 deInitializeHalLog();
422
423 if (async_callback_thread_end() != 0) {
424 STLOG_HAL_E("HAL st21nfc: %s async_callback_thread_end failed", __func__);
425 return -1; // We are doomed, stop it here, NOW !
426 }
427
428 std::string valueStr =
429 android::base::GetProperty("persist.vendor.nfc.streset", "");
430 // do a cold_reset when nfc is off
431 if (valueStr.length() > 0 && nfc_mode_value == 0) {
432 stdll = dlopen(valueStr.c_str(), RTLD_NOW);
433 if (!stdll) {
434 valueStr = VENDOR_LIB_PATH + valueStr + VENDOR_LIB_EXT;
435 stdll = dlopen(valueStr.c_str(), RTLD_NOW);
436 }
437 if (stdll) {
438 STLOG_HAL_D("STReset Cold reset");
439 STEseReset fn = (STEseReset)dlsym(stdll, "cold_reset");
440 if (fn) {
441 int ret = fn();
442 STLOG_HAL_D("STReset Result=%d", ret);
443 }
444 } else {
445 STLOG_HAL_D("%s not found, do nothing.", valueStr.c_str());
446 }
447 }
448
449 STLOG_HAL_D("HAL st21nfc: %s close", __func__);
450 return 0;
451 }
452
StNfc_hal_power_cycle()453 int StNfc_hal_power_cycle() {
454 STLOG_HAL_D("HAL st21nfc: %s", __func__);
455
456 /* check if HAL is closed */
457 int ret = HAL_NFC_STATUS_OK;
458 (void)pthread_mutex_lock(&hal_mtx);
459 if (hal_is_closed) {
460 ret = HAL_NFC_STATUS_FAILED;
461 }
462
463 if (ret != HAL_NFC_STATUS_OK) {
464 (void)pthread_mutex_unlock(&hal_mtx);
465 return ret;
466 }
467 async_callback_post(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
468
469 (void)pthread_mutex_unlock(&hal_mtx);
470 return HAL_NFC_STATUS_OK;
471 }
472
StNfc_hal_factoryReset()473 void StNfc_hal_factoryReset() {
474 STLOG_HAL_D("HAL st21nfc: %s", __func__);
475 // hal_wrapper_factoryReset();
476 // Nothing needed for factory reset in st21nfc case.
477 }
478
StNfc_hal_closeForPowerOffCase()479 int StNfc_hal_closeForPowerOffCase() {
480 STLOG_HAL_D("HAL st21nfc: %s", __func__);
481 if (nfc_mode == 1) {
482 return 0;
483 } else {
484 return StNfc_hal_close(nfc_mode);
485 }
486 }
487
StNfc_hal_getConfig(NfcConfig & config)488 void StNfc_hal_getConfig(NfcConfig& config) {
489 STLOG_HAL_D("HAL st21nfc: %s", __func__);
490 unsigned long num = 0;
491 std::array<uint8_t, 10> buffer;
492
493 buffer.fill(0);
494 long retlen = 0;
495
496 memset(&config, 0x00, sizeof(NfcConfig));
497
498 if (GetNumValue(NAME_CE_ON_SWITCH_OFF_STATE, &num, sizeof(num))) {
499 if (num == 0x1) {
500 nfc_mode = 0x1;
501 }
502 }
503
504 if (GetNumValue(NAME_POLL_BAIL_OUT_MODE, &num, sizeof(num))) {
505 config.nfaPollBailOutMode = num;
506 }
507
508 if (GetNumValue(NAME_ISO_DEP_MAX_TRANSCEIVE, &num, sizeof(num))) {
509 config.maxIsoDepTransceiveLength = num;
510 }
511 if (GetNumValue(NAME_DEFAULT_OFFHOST_ROUTE, &num, sizeof(num))) {
512 config.defaultOffHostRoute = num;
513 }
514 if (GetNumValue(NAME_DEFAULT_NFCF_ROUTE, &num, sizeof(num))) {
515 config.defaultOffHostRouteFelica = num;
516 }
517 if (GetNumValue(NAME_DEFAULT_SYS_CODE_ROUTE, &num, sizeof(num))) {
518 config.defaultSystemCodeRoute = num;
519 }
520 if (GetNumValue(NAME_DEFAULT_SYS_CODE_PWR_STATE, &num, sizeof(num))) {
521 config.defaultSystemCodePowerState = num;
522 }
523 if (GetNumValue(NAME_DEFAULT_ROUTE, &num, sizeof(num))) {
524 config.defaultRoute = num;
525 }
526 if (GetByteArrayValue(NAME_DEVICE_HOST_ALLOW_LIST, (char*)buffer.data(),
527 buffer.size(), &retlen)) {
528 config.hostAllowlist.resize(retlen);
529 for (int i = 0; i < retlen; i++) {
530 config.hostAllowlist[i] = buffer[i];
531 }
532 }
533
534 if (GetNumValue(NAME_OFF_HOST_ESE_PIPE_ID, &num, sizeof(num))) {
535 config.offHostESEPipeId = num;
536 }
537 if (GetNumValue(NAME_OFF_HOST_SIM_PIPE_ID, &num, sizeof(num))) {
538 config.offHostSIMPipeId = num;
539 }
540 if ((GetByteArrayValue(NAME_NFA_PROPRIETARY_CFG, (char*)buffer.data(),
541 buffer.size(), &retlen)) &&
542 (retlen == 9)) {
543 config.nfaProprietaryCfg.protocol18092Active = (uint8_t)buffer[0];
544 config.nfaProprietaryCfg.protocolBPrime = (uint8_t)buffer[1];
545 config.nfaProprietaryCfg.protocolDual = (uint8_t)buffer[2];
546 config.nfaProprietaryCfg.protocol15693 = (uint8_t)buffer[3];
547 config.nfaProprietaryCfg.protocolKovio = (uint8_t)buffer[4];
548 config.nfaProprietaryCfg.protocolMifare = (uint8_t)buffer[5];
549 config.nfaProprietaryCfg.discoveryPollKovio = (uint8_t)buffer[6];
550 config.nfaProprietaryCfg.discoveryPollBPrime = (uint8_t)buffer[7];
551 config.nfaProprietaryCfg.discoveryListenBPrime = (uint8_t)buffer[8];
552 } else {
553 memset(&config.nfaProprietaryCfg, 0xFF, sizeof(ProtocolDiscoveryConfig));
554 }
555 if (GetNumValue(NAME_PRESENCE_CHECK_ALGORITHM, &num, sizeof(num))) {
556 config.presenceCheckAlgorithm = (PresenceCheckAlgorithm)num;
557 }
558
559 if (GetNumValue(NAME_STNFC_USB_CHARGING_MODE, &num, sizeof(num))) {
560 if ((num == 1) && (nfc_mode == 0x1)) {
561 nfc_mode = 0x2;
562 }
563 }
564
565 if (GetByteArrayValue(NAME_OFFHOST_ROUTE_UICC, (char*)buffer.data(),
566 buffer.size(), &retlen)) {
567 config.offHostRouteUicc.resize(retlen);
568 for (int i = 0; i < retlen; i++) {
569 config.offHostRouteUicc[i] = buffer[i];
570 }
571 }
572
573 if (GetByteArrayValue(NAME_OFFHOST_ROUTE_ESE, (char*)buffer.data(),
574 buffer.size(), &retlen)) {
575 config.offHostRouteEse.resize(retlen);
576 for (int i = 0; i < retlen; i++) {
577 config.offHostRouteEse[i] = buffer[i];
578 }
579 }
580
581 if (GetNumValue(NAME_DEFAULT_ISODEP_ROUTE, &num, sizeof(num))) {
582 config.defaultIsoDepRoute = num;
583 }
584 }
585
StNfc_hal_setLogging(bool enable)586 void StNfc_hal_setLogging(bool enable) {
587 dbg_logging = enable;
588 hal_wrapper_setFwLogging(enable);
589 if (dbg_logging && hal_conf_trace_level < STNFC_TRACE_LEVEL_VERBOSE) {
590 hal_trace_level = STNFC_TRACE_LEVEL_VERBOSE;
591 } else {
592 hal_trace_level = hal_conf_trace_level;
593 }
594 }
595
StNfc_hal_isLoggingEnabled()596 bool StNfc_hal_isLoggingEnabled() { return dbg_logging; }
597