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