• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "hal_fd.h"
32 #include "halcore.h"
33 #include "st21nfc_dev.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 
43 #define CRC_PRESET_A 0x6363
44 #define CRC_PRESET_B 0xFFFF
45 #define Type_A 0
46 #define Type_B 1
47 
48 
49 bool dbg_logging = false;
50 
51 extern void HalCoreCallback(void* context, uint32_t event, const void* d,
52                             size_t length);
53 extern bool I2cOpenLayer(void* dev, HAL_CALLBACK callb, HALHANDLE* pHandle);
54 
55 typedef int (*STEseReset)(void);
56 
57 const char* halVersion = "ST21NFC AIDL Version 1.0.0";
58 
59 uint8_t cmd_set_nfc_mode_enable[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
60 uint8_t hal_is_closed = 1;
61 pthread_mutex_t hal_mtx = PTHREAD_MUTEX_INITIALIZER;
62 st21nfc_dev_t dev;
63 int nfc_mode = 0;
64 uint8_t nci_cmd[256];
65 
66 /*
67  * NCI HAL method implementations. These must be overridden
68  */
69 
70 extern bool hal_wrapper_open(st21nfc_dev_t* dev, nfc_stack_callback_t* p_cback,
71                              nfc_stack_data_callback_t* p_data_cback,
72                              HALHANDLE* pHandle);
73 
74 extern int hal_wrapper_close(int call_cb, int nfc_mode);
75 
76 extern void hal_wrapper_send_config();
77 extern void hal_wrapper_factoryReset();
78 extern void hal_wrapper_set_observer_mode(uint8_t enable, bool per_tech_cmd);
79 extern void hal_wrapper_get_observer_mode();
80 
81 /* Make sure to always post nfc_stack_callback_t in a separate thread.
82 This prevents a possible deadlock in upper layer on some sequences.
83 We need to synchronize finely for the callback called for hal close,
84 otherwise the upper layer either does not receive the event, or deadlocks,
85 because the HAL is closing while the callback may be blocked.
86  */
87 static struct async_callback_struct {
88   pthread_mutex_t mutex;
89   pthread_cond_t cond;
90   pthread_t thr;
91   int event_pending;
92   int stop_thread;
93   int thread_running;
94   nfc_event_t event;
95   nfc_status_t event_status;
96 } async_callback_data;
97 
async_callback_thread_fct(void * arg)98 static void* async_callback_thread_fct(void* arg) {
99   int ret;
100   struct async_callback_struct* pcb_data = (struct async_callback_struct*)arg;
101 
102   ret = pthread_mutex_lock(&pcb_data->mutex);
103   if (ret != 0) {
104     STLOG_HAL_E("HAL: %s pthread_mutex_lock failed", __func__);
105     goto error;
106   }
107 
108   do {
109     if (pcb_data->event_pending == 0) {
110       ret = pthread_cond_wait(&pcb_data->cond, &pcb_data->mutex);
111       if (ret != 0) {
112         STLOG_HAL_E("HAL: %s pthread_cond_wait failed", __func__);
113         break;
114       }
115     }
116 
117     if (pcb_data->event_pending) {
118       nfc_event_t event = pcb_data->event;
119       nfc_status_t event_status = pcb_data->event_status;
120       int ending = pcb_data->stop_thread;
121       pcb_data->event_pending = 0;
122       ret = pthread_cond_signal(&pcb_data->cond);
123       if (ret != 0) {
124         STLOG_HAL_E("HAL: %s pthread_cond_signal failed", __func__);
125         break;
126       }
127       if (ending) {
128         pcb_data->thread_running = 0;
129       }
130       ret = pthread_mutex_unlock(&pcb_data->mutex);
131       if (ret != 0) {
132         STLOG_HAL_E("HAL: %s pthread_mutex_unlock failed", __func__);
133       }
134       STLOG_HAL_D("HAL st21nfc: %s event %hhx status %hhx", __func__, event,
135                   event_status);
136       dev.p_cback_unwrap(event, event_status);
137       if (ending) {
138         return NULL;
139       }
140       ret = pthread_mutex_lock(&pcb_data->mutex);
141       if (ret != 0) {
142         STLOG_HAL_E("HAL: %s pthread_mutex_lock failed", __func__);
143         goto error;
144       }
145     }
146   } while (pcb_data->stop_thread == 0 || pcb_data->event_pending);
147 
148   ret = pthread_mutex_unlock(&pcb_data->mutex);
149   if (ret != 0) {
150     STLOG_HAL_E("HAL: %s pthread_mutex_unlock failed", __func__);
151   }
152 
153 error:
154   pcb_data->thread_running = 0;
155   return NULL;
156 }
157 
async_callback_thread_start()158 static int async_callback_thread_start() {
159   int ret;
160 
161   memset(&async_callback_data, 0, sizeof(async_callback_data));
162 
163   ret = pthread_mutex_init(&async_callback_data.mutex, NULL);
164   if (ret != 0) {
165     STLOG_HAL_E("HAL: %s pthread_mutex_init failed", __func__);
166     return ret;
167   }
168 
169   ret = pthread_cond_init(&async_callback_data.cond, NULL);
170   if (ret != 0) {
171     STLOG_HAL_E("HAL: %s pthread_cond_init failed", __func__);
172     return ret;
173   }
174 
175   async_callback_data.thread_running = 1;
176 
177   ret = pthread_create(&async_callback_data.thr, NULL,
178                        async_callback_thread_fct, &async_callback_data);
179   if (ret != 0) {
180     STLOG_HAL_E("HAL: %s pthread_create failed", __func__);
181     async_callback_data.thread_running = 0;
182     return ret;
183   }
184 
185   return 0;
186 }
187 
async_callback_thread_end()188 static int async_callback_thread_end() {
189   if (async_callback_data.thread_running != 0) {
190     int ret;
191 
192     ret = pthread_mutex_lock(&async_callback_data.mutex);
193     if (ret != 0) {
194       STLOG_HAL_E("HAL: %s pthread_mutex_lock failed", __func__);
195       return ret;
196     }
197 
198     async_callback_data.stop_thread = 1;
199 
200     // Wait for the thread to have no event pending
201     while (async_callback_data.thread_running &&
202            async_callback_data.event_pending) {
203       ret = pthread_cond_signal(&async_callback_data.cond);
204       if (ret != 0) {
205         STLOG_HAL_E("HAL: %s pthread_cond_signal failed", __func__);
206         return ret;
207       }
208       ret = pthread_cond_wait(&async_callback_data.cond,
209                               &async_callback_data.mutex);
210       if (ret != 0) {
211         STLOG_HAL_E("HAL: %s pthread_cond_wait failed", __func__);
212         break;
213       }
214     }
215 
216     ret = pthread_mutex_unlock(&async_callback_data.mutex);
217     if (ret != 0) {
218       STLOG_HAL_E("HAL: %s pthread_mutex_unlock failed", __func__);
219       return ret;
220     }
221 
222     ret = pthread_cond_signal(&async_callback_data.cond);
223     if (ret != 0) {
224       STLOG_HAL_E("HAL: %s pthread_cond_signal failed", __func__);
225       return ret;
226     }
227 
228     ret = pthread_join(async_callback_data.thr, (void**)NULL);
229     if (ret != 0) {
230       STLOG_HAL_E("HAL: %s pthread_join failed", __func__);
231       return ret;
232     }
233   }
234   return 0;
235 }
236 
async_callback_post(nfc_event_t event,nfc_status_t event_status)237 static void async_callback_post(nfc_event_t event, nfc_status_t event_status) {
238   int ret;
239 
240   if (pthread_equal(pthread_self(), async_callback_data.thr)) {
241     dev.p_cback_unwrap(event, event_status);
242   }
243 
244   ret = pthread_mutex_lock(&async_callback_data.mutex);
245   if (ret != 0) {
246     STLOG_HAL_E("HAL: %s pthread_mutex_lock failed", __func__);
247     return;
248   }
249 
250   if (async_callback_data.thread_running == 0) {
251     (void)pthread_mutex_unlock(&async_callback_data.mutex);
252     STLOG_HAL_E("HAL: %s thread is not running", __func__);
253     dev.p_cback_unwrap(event, event_status);
254     return;
255   }
256 
257   while (async_callback_data.event_pending) {
258     ret = pthread_cond_wait(&async_callback_data.cond,
259                             &async_callback_data.mutex);
260     if (ret != 0) {
261       STLOG_HAL_E("HAL: %s pthread_cond_wait failed", __func__);
262       return;
263     }
264   }
265 
266   async_callback_data.event_pending = 1;
267   async_callback_data.event = event;
268   async_callback_data.event_status = event_status;
269 
270   ret = pthread_mutex_unlock(&async_callback_data.mutex);
271   if (ret != 0) {
272     STLOG_HAL_E("HAL: %s pthread_mutex_unlock failed", __func__);
273     return;
274   }
275 
276   ret = pthread_cond_signal(&async_callback_data.cond);
277   if (ret != 0) {
278     STLOG_HAL_E("HAL: %s pthread_cond_signal failed", __func__);
279     return;
280   }
281 }
282 /* ------ */
283 
StNfc_hal_open(nfc_stack_callback_t * p_cback,nfc_stack_data_callback_t * p_data_cback)284 int StNfc_hal_open(nfc_stack_callback_t* p_cback,
285                    nfc_stack_data_callback_t* p_data_cback) {
286   bool result = false;
287 
288   STLOG_HAL_D("HAL st21nfc: %s %s", __func__, halVersion);
289 
290   (void)pthread_mutex_lock(&hal_mtx);
291 
292   if (!hal_is_closed) {
293     hal_wrapper_close(0, nfc_mode);
294   }
295 
296   dev.p_cback = p_cback;  // will be replaced by wrapper version
297   dev.p_cback_unwrap = p_cback;
298   dev.p_data_cback = p_data_cback;
299   // Initialize and get global logging level
300   InitializeSTLogLevel();
301 
302   if ((hal_is_closed || !async_callback_data.thread_running) &&
303       (async_callback_thread_start() != 0)) {
304     dev.p_cback(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   result =
309       hal_wrapper_open(&dev, async_callback_post, p_data_cback, &(dev.hHAL));
310 
311   if (!result || !(dev.hHAL)) {
312     async_callback_post(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
313     (void)pthread_mutex_unlock(&hal_mtx);
314     return -1;  // We are doomed, stop it here, NOW !
315   }
316   hal_is_closed = 0;
317   (void)pthread_mutex_unlock(&hal_mtx);
318   return 0;
319 }
320 
StNfc_hal_write(uint16_t data_len,const uint8_t * p_data)321 int StNfc_hal_write(uint16_t data_len, const uint8_t* p_data) {
322   STLOG_HAL_D("HAL st21nfc: %s", __func__);
323 
324   uint8_t NCI_ANDROID_PASSIVE_OBSERVER_PREFIX[] = {0x2f, 0x0c, 0x02, 0x02};
325   uint8_t NCI_ANDROID_PASSIVE_OBSERVER_PER_TECH_PREFIX[] = {0x2f, 0x0c, 0x02,
326                                                             0x05};
327   uint8_t NCI_QUERY_ANDROID_PASSIVE_OBSERVER_PREFIX[] = {0x2f, 0x0c, 0x01, 0x4};
328   uint8_t NCI_ANDROID_PREFIX[] = {0x2f, 0x0c};
329   uint8_t RF_GET_LISTEN_OBSERVE_MODE_STATE[5] = {0x21, 0x17, 0x00};
330   uint8_t RF_SET_LISTEN_OBSERVE_MODE_STATE[4] = {0x21, 0x16, 0x01, 0x0};
331   uint8_t CORE_GET_CONFIG_OBSERVER[5] = {0x20, 0x03, 0x02, 0x01, 0xa3};
332   uint8_t CORE_SET_CONFIG_OBSERVER[7] = {0x20, 0x02, 0x04, 0x01,
333                                          0xa3, 0x01, 0x00};
334   uint8_t* mGetObserve = CORE_GET_CONFIG_OBSERVER;
335   uint8_t mGetObserve_size = 5;
336   uint8_t* mSetObserve = CORE_SET_CONFIG_OBSERVER;
337   uint8_t mSetObserve_size = 7;
338   uint8_t mTechObserved = 0x0;
339   /* check if HAL is closed */
340   int ret = (int)data_len;
341   (void)pthread_mutex_lock(&hal_mtx);
342   if (hal_is_closed) {
343     ret = 0;
344   }
345 
346   if (!ret) {
347     (void)pthread_mutex_unlock(&hal_mtx);
348     return ret;
349   }
350 
351   if (data_len == 4 &&
352       !memcmp(p_data, NCI_QUERY_ANDROID_PASSIVE_OBSERVER_PREFIX,
353               sizeof(NCI_QUERY_ANDROID_PASSIVE_OBSERVER_PREFIX))) {
354     hal_wrapper_get_observer_mode();
355     if (hal_fd_getFwCap()->ObserveMode == 2) {
356       mGetObserve = RF_GET_LISTEN_OBSERVE_MODE_STATE;
357       mGetObserve_size = 3;
358     }
359     if (!HalSendDownstream(dev.hHAL, mGetObserve, mGetObserve_size)) {
360       STLOG_HAL_E("HAL st21nfc %s  SendDownstream failed", __func__);
361       (void)pthread_mutex_unlock(&hal_mtx);
362       return 0;
363     }
364   }
365 
366   else if (data_len == 5 &&
367            !memcmp(p_data, NCI_ANDROID_PASSIVE_OBSERVER_PREFIX,
368                    sizeof(NCI_ANDROID_PASSIVE_OBSERVER_PREFIX))) {
369     if (hal_fd_getFwCap()->ObserveMode == 2) {
370       mSetObserve = RF_SET_LISTEN_OBSERVE_MODE_STATE;
371       mSetObserve_size = 4;
372       if (p_data[4]) {
373         mTechObserved = 0x7;
374       }
375       mSetObserve[3] = mTechObserved;
376       hal_wrapper_set_observer_mode(mTechObserved, false);
377     } else {
378       mSetObserve[6] = p_data[4];
379       hal_wrapper_set_observer_mode(p_data[4], false);
380     }
381 
382     if (!HalSendDownstream(dev.hHAL, mSetObserve, mSetObserve_size)) {
383       STLOG_HAL_E("HAL st21nfc %s  SendDownstream failed", __func__);
384       (void)pthread_mutex_unlock(&hal_mtx);
385       return 0;
386     }
387   } else if (data_len == 5 &&
388              !memcmp(p_data, NCI_ANDROID_PASSIVE_OBSERVER_PER_TECH_PREFIX,
389                      sizeof(NCI_ANDROID_PASSIVE_OBSERVER_PER_TECH_PREFIX))) {
390     mSetObserve = RF_SET_LISTEN_OBSERVE_MODE_STATE;
391     mSetObserve_size = 4;
392     if (p_data[4]) {
393       mTechObserved = p_data[4];
394     }
395     mSetObserve[3] = mTechObserved;
396     hal_wrapper_set_observer_mode(mTechObserved, true);
397     if (!HalSendDownstream(dev.hHAL, mSetObserve, mSetObserve_size)) {
398       STLOG_HAL_E("HAL st21nfc %s  SendDownstream failed", __func__);
399       (void)pthread_mutex_unlock(&hal_mtx);
400       return 0;
401     }
402   } else if (!memcmp(p_data, NCI_ANDROID_PREFIX, sizeof(NCI_ANDROID_PREFIX)) &&
403              p_data[3] == 0x6) {
404     DispHal("TX DATA", (p_data), data_len);
405 
406     memcpy(nci_cmd+3, p_data+4, 4);
407     nci_cmd[0] = 0x2f;
408     nci_cmd[1] = 0x19;
409 
410     int index = 8;
411     int ll_index = 7;
412     uint8_t nci_length = 0;
413     uint16_t crc = 0;
414     bool prefix_match = false;
415     bool exact_match = true;
416 
417     while (index < data_len) {
418       // Read the Type field (1 byte)
419       uint8_t type_field = p_data[index];
420       int tlv_len = p_data[index + 1];
421       prefix_match = false;
422       exact_match = true;
423       if (p_data[index] == 0x01) {
424         crc = iso14443_crc(p_data + index + 3, (uint8_t)((tlv_len - 1) / 2),
425                            Type_B);
426       } else if ((p_data[index] & 0xF0) == 0x00) {
427         crc = iso14443_crc(p_data + index + 3, (uint8_t)((tlv_len - 1) / 2),
428                            Type_A);
429       } else {
430         prefix_match = true;
431       }
432 
433       nci_cmd[ll_index++] = p_data[index++];
434       nci_cmd[ll_index++] =
435           (!prefix_match) ? p_data[index++] + 4 : p_data[index++];
436       nci_cmd[ll_index++] = p_data[index++];
437 
438       memcpy(nci_cmd + ll_index, p_data + index, (uint8_t)((tlv_len - 1) / 2));
439       ll_index += (tlv_len - 1) / 2;
440       index += (tlv_len - 1) / 2;
441       int crc_index = 0;
442       if (!prefix_match) {
443         crc_index = ll_index;
444         nci_cmd[ll_index++] = (uint8_t)crc;
445         nci_cmd[ll_index++] = (uint8_t)(crc >> 8);
446       }
447 
448       memcpy(nci_cmd + ll_index, p_data + index, (tlv_len - 1) / 2);
449       for (int i = 0; i < (tlv_len - 1) / 2; ++i) {
450         if (p_data[index + i] != 0xFF) {
451             exact_match = false;
452             break;
453         }
454       }
455       ll_index += (tlv_len - 1) / 2;
456       index += (tlv_len - 1) / 2;
457       uint8_t crc_mask = exact_match ? 0xFF : 0x00;
458       if (!prefix_match) {
459         nci_cmd[ll_index++] = crc_mask;
460         nci_cmd[ll_index++] = crc_mask;
461 
462         if (!exact_match) {
463         nci_cmd[crc_index] = crc_mask;
464         nci_cmd[crc_index +1] = crc_mask;
465         }
466 
467       }
468     }
469     nci_length = ll_index;
470     nci_cmd[2] = ll_index -3;
471 
472     if (!HalSendDownstream(dev.hHAL, nci_cmd, nci_length)) {
473       STLOG_HAL_E("HAL st21nfc %s  SendDownstream failed", __func__);
474       (void)pthread_mutex_unlock(&hal_mtx);
475       return 0;
476     }
477   } else if (!memcmp(p_data, NCI_ANDROID_PREFIX, sizeof(NCI_ANDROID_PREFIX)) &&
478              p_data[3] == 0x9) {
479     DispHal("TX DATA", (p_data), data_len);
480     memcpy(nci_cmd + 3, p_data + 4, data_len - 4);
481 
482     uint16_t crc = iso14443_crc(nci_cmd + 7, nci_cmd[5] - 1, Type_A);
483 
484     uint8_t len = p_data[2];
485     nci_cmd[0] = 0x2f;
486     nci_cmd[1] = 0x1d;
487     nci_cmd[5] = nci_cmd[5] + 2;
488     nci_cmd[data_len - 1] = (uint8_t)crc;
489     nci_cmd[data_len] = (uint8_t)(crc >> 8);
490 
491     nci_cmd[2] = p_data[2] + 1;
492     if (!HalSendDownstream(dev.hHAL, nci_cmd, nci_cmd[2] + 3)) {
493       STLOG_HAL_E("HAL st21nfc %s  SendDownstream failed", __func__);
494       (void)pthread_mutex_unlock(&hal_mtx);
495       return 0;
496     }
497   } else if (!HalSendDownstream(dev.hHAL, p_data, data_len)) {
498     STLOG_HAL_E("HAL st21nfc %s  SendDownstream failed", __func__);
499     (void)pthread_mutex_unlock(&hal_mtx);
500     return 0;
501   }
502   (void)pthread_mutex_unlock(&hal_mtx);
503 
504   return ret;
505 }
506 
StNfc_hal_core_initialized()507 int StNfc_hal_core_initialized() {
508   STLOG_HAL_D("HAL st21nfc: %s", __func__);
509 
510   (void)pthread_mutex_lock(&hal_mtx);
511   hal_wrapper_send_config();
512   (void)pthread_mutex_unlock(&hal_mtx);
513 
514   return 0;  // return != 0 to signal ready immediate
515 }
516 
StNfc_hal_pre_discover()517 int StNfc_hal_pre_discover() {
518   STLOG_HAL_D("HAL st21nfc: %s", __func__);
519   async_callback_post(HAL_NFC_PRE_DISCOVER_CPLT_EVT, HAL_NFC_STATUS_OK);
520   // callback directly if no vendor-specific pre-discovery actions are needed
521   return 0;
522 }
523 
StNfc_hal_close(int nfc_mode_value)524 int StNfc_hal_close(int nfc_mode_value) {
525   void* stdll = nullptr;
526   STLOG_HAL_D("HAL st21nfc: %s nfc_mode = %d", __func__, nfc_mode_value);
527 
528   /* check if HAL is closed */
529   (void)pthread_mutex_lock(&hal_mtx);
530   if (hal_is_closed) {
531     (void)pthread_mutex_unlock(&hal_mtx);
532     return 1;
533   }
534   if (hal_wrapper_close(1, nfc_mode_value) == -1) {
535     hal_is_closed = 1;
536     (void)pthread_mutex_unlock(&hal_mtx);
537     return 1;
538   }
539   hal_is_closed = 1;
540   (void)pthread_mutex_unlock(&hal_mtx);
541 
542   deInitializeHalLog();
543 
544   if (async_callback_thread_end() != 0) {
545     STLOG_HAL_E("HAL st21nfc: %s async_callback_thread_end failed", __func__);
546     return -1;  // We are doomed, stop it here, NOW !
547   }
548 
549   std::string valueStr =
550       android::base::GetProperty("persist.vendor.nfc.streset", "");
551   // do a cold_reset when nfc is off
552   if (valueStr.length() > 0 && nfc_mode_value == 0) {
553     stdll = dlopen(valueStr.c_str(), RTLD_NOW);
554     if (!stdll) {
555       valueStr = VENDOR_LIB_PATH + valueStr + VENDOR_LIB_EXT;
556       stdll = dlopen(valueStr.c_str(), RTLD_NOW);
557     }
558     if (stdll) {
559       STLOG_HAL_D("STReset Cold reset");
560       STEseReset fn = (STEseReset)dlsym(stdll, "cold_reset");
561       if (fn) {
562         int ret = fn();
563         STLOG_HAL_D("STReset Result=%d", ret);
564       }
565     } else {
566       STLOG_HAL_D("%s not found, do nothing.", valueStr.c_str());
567     }
568   }
569 
570   STLOG_HAL_D("HAL st21nfc: %s close", __func__);
571   return 0;
572 }
573 
StNfc_hal_power_cycle()574 int StNfc_hal_power_cycle() {
575   STLOG_HAL_D("HAL st21nfc: %s", __func__);
576 
577   /* check if HAL is closed */
578   int ret = HAL_NFC_STATUS_OK;
579   (void)pthread_mutex_lock(&hal_mtx);
580   if (hal_is_closed) {
581     ret = HAL_NFC_STATUS_FAILED;
582   }
583 
584   if (ret != HAL_NFC_STATUS_OK) {
585     (void)pthread_mutex_unlock(&hal_mtx);
586     return ret;
587   }
588   async_callback_post(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
589 
590   (void)pthread_mutex_unlock(&hal_mtx);
591   return HAL_NFC_STATUS_OK;
592 }
593 
StNfc_hal_factoryReset()594 void StNfc_hal_factoryReset() {
595   STLOG_HAL_D("HAL st21nfc: %s", __func__);
596   // hal_wrapper_factoryReset();
597   //  Nothing needed for factory reset in st21nfc case.
598 }
599 
StNfc_hal_closeForPowerOffCase()600 int StNfc_hal_closeForPowerOffCase() {
601   STLOG_HAL_D("HAL st21nfc: %s", __func__);
602   if (nfc_mode == 1) {
603     return 0;
604   } else {
605     return StNfc_hal_close(nfc_mode);
606   }
607 }
608 
StNfc_hal_getConfig(NfcConfig & config)609 void StNfc_hal_getConfig(NfcConfig& config) {
610   STLOG_HAL_D("HAL st21nfc: %s", __func__);
611   unsigned long num = 0;
612   std::array<uint8_t, 10> buffer;
613 
614   buffer.fill(0);
615   long retlen = 0;
616 
617   memset(&config, 0x00, sizeof(NfcConfig));
618 
619   if (GetNumValue(NAME_CE_ON_SWITCH_OFF_STATE, &num, sizeof(num))) {
620     if (num == 0x1) {
621       nfc_mode = 0x1;
622     }
623   }
624 
625   if (GetNumValue(NAME_POLL_BAIL_OUT_MODE, &num, sizeof(num))) {
626     config.nfaPollBailOutMode = num;
627   }
628 
629   if (GetNumValue(NAME_ISO_DEP_MAX_TRANSCEIVE, &num, sizeof(num))) {
630     config.maxIsoDepTransceiveLength = num;
631   }
632   if (GetNumValue(NAME_DEFAULT_OFFHOST_ROUTE, &num, sizeof(num))) {
633     config.defaultOffHostRoute = num;
634   }
635   if (GetNumValue(NAME_DEFAULT_NFCF_ROUTE, &num, sizeof(num))) {
636     config.defaultOffHostRouteFelica = num;
637   }
638   if (GetNumValue(NAME_DEFAULT_SYS_CODE_ROUTE, &num, sizeof(num))) {
639     config.defaultSystemCodeRoute = num;
640   }
641   if (GetNumValue(NAME_DEFAULT_SYS_CODE_PWR_STATE, &num, sizeof(num))) {
642     config.defaultSystemCodePowerState = num;
643   }
644   if (GetNumValue(NAME_DEFAULT_ROUTE, &num, sizeof(num))) {
645     config.defaultRoute = num;
646   }
647   if (GetByteArrayValue(NAME_DEVICE_HOST_ALLOW_LIST, (char*)buffer.data(),
648                         buffer.size(), &retlen)) {
649     config.hostAllowlist.resize(retlen);
650     for (int i = 0; i < retlen; i++) {
651       config.hostAllowlist[i] = buffer[i];
652     }
653   }
654 
655   if (GetNumValue(NAME_OFF_HOST_ESE_PIPE_ID, &num, sizeof(num))) {
656     config.offHostESEPipeId = num;
657   }
658   if (GetNumValue(NAME_OFF_HOST_SIM_PIPE_ID, &num, sizeof(num))) {
659     config.offHostSIMPipeId = num;
660   }
661   if ((GetByteArrayValue(NAME_NFA_PROPRIETARY_CFG, (char*)buffer.data(),
662                          buffer.size(), &retlen)) &&
663       (retlen == 9)) {
664     config.nfaProprietaryCfg.protocol18092Active = (uint8_t)buffer[0];
665     config.nfaProprietaryCfg.protocolBPrime = (uint8_t)buffer[1];
666     config.nfaProprietaryCfg.protocolDual = (uint8_t)buffer[2];
667     config.nfaProprietaryCfg.protocol15693 = (uint8_t)buffer[3];
668     config.nfaProprietaryCfg.protocolKovio = (uint8_t)buffer[4];
669     config.nfaProprietaryCfg.protocolMifare = (uint8_t)buffer[5];
670     config.nfaProprietaryCfg.discoveryPollKovio = (uint8_t)buffer[6];
671     config.nfaProprietaryCfg.discoveryPollBPrime = (uint8_t)buffer[7];
672     config.nfaProprietaryCfg.discoveryListenBPrime = (uint8_t)buffer[8];
673   } else {
674     memset(&config.nfaProprietaryCfg, 0xFF, sizeof(ProtocolDiscoveryConfig));
675   }
676   if (GetNumValue(NAME_PRESENCE_CHECK_ALGORITHM, &num, sizeof(num))) {
677     config.presenceCheckAlgorithm = (PresenceCheckAlgorithm)num;
678   }
679 
680   if (GetNumValue(NAME_STNFC_USB_CHARGING_MODE, &num, sizeof(num))) {
681     if ((num == 1) && (nfc_mode == 0x1)) {
682       nfc_mode = 0x2;
683     }
684   }
685 
686   if (GetByteArrayValue(NAME_OFFHOST_ROUTE_UICC, (char*)buffer.data(),
687                         buffer.size(), &retlen)) {
688     config.offHostRouteUicc.resize(retlen);
689     for (int i = 0; i < retlen; i++) {
690       config.offHostRouteUicc[i] = buffer[i];
691     }
692   }
693 
694   if (GetByteArrayValue(NAME_OFFHOST_ROUTE_ESE, (char*)buffer.data(),
695                         buffer.size(), &retlen)) {
696     config.offHostRouteEse.resize(retlen);
697     for (int i = 0; i < retlen; i++) {
698       config.offHostRouteEse[i] = buffer[i];
699     }
700   }
701 
702   if (GetNumValue(NAME_DEFAULT_ISODEP_ROUTE, &num, sizeof(num))) {
703     config.defaultIsoDepRoute = num;
704   }
705 }
706 
StNfc_hal_setLogging(bool enable)707 void StNfc_hal_setLogging(bool enable) {
708   dbg_logging = enable;
709   hal_wrapper_setFwLogging(enable);
710   if (dbg_logging && hal_conf_trace_level < STNFC_TRACE_LEVEL_VERBOSE) {
711     hal_trace_level = STNFC_TRACE_LEVEL_VERBOSE;
712   } else {
713     hal_trace_level = hal_conf_trace_level;
714   }
715 }
716 
StNfc_hal_isLoggingEnabled()717 bool StNfc_hal_isLoggingEnabled() { return dbg_logging; }
718 
StNfc_hal_dump(int fd)719 void StNfc_hal_dump(int fd) { hal_wrapper_dumplog(fd); }
720 
iso14443_crc(const uint8_t * data,size_t szLen,int type)721 uint16_t iso14443_crc(const uint8_t* data, size_t szLen, int type) {
722   uint16_t tempCrc;
723   if (type == Type_A) {
724     tempCrc = (unsigned short)CRC_PRESET_A;
725   } else {
726     tempCrc = (unsigned short)CRC_PRESET_B;
727   }
728   do {
729     uint8_t bt;
730     bt = *data++;
731     bt = (bt ^ (uint8_t)(tempCrc & 0x00FF));
732     bt = (bt ^ (bt << 4));
733     tempCrc = (tempCrc >> 8) ^ ((uint32_t)bt << 8) ^ ((uint32_t)bt << 3) ^
734               ((uint32_t)bt >> 4);
735   } while (--szLen);
736 
737   return tempCrc;
738 }
739