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