1 /******************************************************************************
2 *
3 * Copyright (C) 2017 ST Microelectronics S.A.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *
18 ******************************************************************************/
19 #define LOG_TAG "NfcNciHalWrapper"
20 #include <cutils/properties.h>
21 #include <errno.h>
22 #include <hardware/nfc.h>
23 #include <log/log.h>
24 #include <string.h>
25 #include <unistd.h>
26
27 #include "android_logmsg.h"
28 #include "hal_fd.h"
29 #include "halcore.h"
30 #include "st21nfc_dev.h"
31
32 extern void HalCoreCallback(void* context, uint32_t event, const void* d,
33 size_t length);
34 extern bool I2cOpenLayer(void* dev, HAL_CALLBACK callb, HALHANDLE* pHandle);
35 extern void I2cCloseLayer();
36 extern void I2cRecovery();
37
38 static void halWrapperDataCallback(uint16_t data_len, uint8_t* p_data);
39 static void halWrapperCallback(uint8_t event, uint8_t event_status);
40
41 nfc_stack_callback_t* mHalWrapperCallback = NULL;
42 nfc_stack_data_callback_t* mHalWrapperDataCallback = NULL;
43 hal_wrapper_state_e mHalWrapperState = HAL_WRAPPER_STATE_CLOSED;
44 HALHANDLE mHalHandle = NULL;
45
46 uint8_t mClfMode;
47 uint8_t mFwUpdateTaskMask;
48 int mRetryFwDwl;
49 uint8_t mFwUpdateResMask = 0;
50 uint8_t* ConfigBuffer = NULL;
51 uint8_t mError_count = 0;
52 bool mIsActiveRW = false;
53 pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
54 pthread_mutex_t mutex_activerw = PTHREAD_MUTEX_INITIALIZER;
55 pthread_cond_t ready_cond = PTHREAD_COND_INITIALIZER;
56
57 static const uint8_t ApduGetAtr[] = {0x2F, 0x04, 0x05, 0x80,
58 0x8A, 0x00, 0x00, 0x04};
59
60 static const uint8_t nciHeaderPropSetConfig[9] = {0x2F, 0x02, 0x98, 0x04, 0x00,
61 0x14, 0x01, 0x00, 0x92};
62 static uint8_t nciPropEnableFwDbgTraces[256];
63 static uint8_t nciPropGetFwDbgTracesConfig[] = {0x2F, 0x02, 0x05, 0x03,
64 0x00, 0x14, 0x01, 0x00};
65 static bool isDebuggable;
66
67 bool mReadFwConfigDone = false;
68
69 bool mHciCreditLent = false;
70 bool mfactoryReset = false;
71 bool ready_flag = 0;
72 bool mTimerStarted = false;
73 bool mFieldInfoTimerStarted = false;
74 bool forceRecover = false;
75 unsigned long hal_field_timer = 0;
76
77 static bool sEnableFwLog = false;
78
wait_ready()79 void wait_ready() {
80 pthread_mutex_lock(&mutex);
81 while (!ready_flag) {
82 pthread_cond_wait(&ready_cond, &mutex);
83 }
84 pthread_mutex_unlock(&mutex);
85 }
86
set_ready(bool ready)87 void set_ready(bool ready) {
88 pthread_mutex_lock(&mutex);
89 ready_flag = ready;
90 pthread_cond_signal(&ready_cond);
91 pthread_mutex_unlock(&mutex);
92 }
93
hal_wrapper_open(st21nfc_dev_t * dev,nfc_stack_callback_t * p_cback,nfc_stack_data_callback_t * p_data_cback,HALHANDLE * pHandle)94 bool hal_wrapper_open(st21nfc_dev_t* dev, nfc_stack_callback_t* p_cback,
95 nfc_stack_data_callback_t* p_data_cback,
96 HALHANDLE* pHandle) {
97 bool result;
98
99 STLOG_HAL_D("%s", __func__);
100
101 mFwUpdateResMask = hal_fd_init();
102 mRetryFwDwl = 5;
103 mFwUpdateTaskMask = 0;
104
105 mHalWrapperState = HAL_WRAPPER_STATE_OPEN;
106 mHciCreditLent = false;
107 mReadFwConfigDone = false;
108 mError_count = 0;
109
110 mHalWrapperCallback = p_cback;
111 mHalWrapperDataCallback = p_data_cback;
112
113 dev->p_data_cback = halWrapperDataCallback;
114 dev->p_cback = halWrapperCallback;
115
116 result = I2cOpenLayer(dev, HalCoreCallback, pHandle);
117
118 if (!result || !(*pHandle)) {
119 return -1; // We are doomed, stop it here, NOW !
120 }
121
122 isDebuggable = property_get_int32("ro.debuggable", 0);
123 mHalHandle = *pHandle;
124
125 HalSendDownstreamTimer(mHalHandle, 10000);
126
127 return 1;
128 }
129
hal_wrapper_close(int call_cb,int nfc_mode)130 int hal_wrapper_close(int call_cb, int nfc_mode) {
131 STLOG_HAL_V("%s - Sending PROP_NFC_MODE_SET_CMD(%d)", __func__, nfc_mode);
132 uint8_t propNfcModeSetCmdQb[] = {0x2f, 0x02, 0x02, 0x02, (uint8_t)nfc_mode};
133
134 mHalWrapperState = HAL_WRAPPER_STATE_CLOSING;
135 // Send PROP_NFC_MODE_SET_CMD
136 if (!HalSendDownstreamTimer(mHalHandle, propNfcModeSetCmdQb,
137 sizeof(propNfcModeSetCmdQb), 40)) {
138 STLOG_HAL_E("NFC-NCI HAL: %s HalSendDownstreamTimer failed", __func__);
139 return -1;
140 }
141 // Let the CLF receive and process this
142 usleep(50000);
143
144 I2cCloseLayer();
145 if (call_cb) mHalWrapperCallback(HAL_NFC_CLOSE_CPLT_EVT, HAL_NFC_STATUS_OK);
146
147 return 1;
148 }
149
hal_wrapper_send_core_config_prop()150 void hal_wrapper_send_core_config_prop() {
151 long retlen = 0;
152 int isfound = 0;
153
154 // allocate buffer for setting parameters
155 ConfigBuffer = (uint8_t*)malloc(256 * sizeof(uint8_t));
156 if (ConfigBuffer != NULL) {
157 isfound = GetByteArrayValue(NAME_CORE_CONF_PROP, (char*)ConfigBuffer, 256,
158 &retlen);
159
160 if (isfound > 0) {
161 STLOG_HAL_V("%s - Enter", __func__);
162 set_ready(0);
163
164 if (!HalSendDownstreamTimer(mHalHandle, ConfigBuffer, retlen, 500)) {
165 STLOG_HAL_E("NFC-NCI HAL: %s SendDownstream failed", __func__);
166 }
167 mHalWrapperState = HAL_WRAPPER_STATE_PROP_CONFIG;
168 wait_ready();
169 }
170 free(ConfigBuffer);
171 ConfigBuffer = NULL;
172 }
173 }
174
hal_wrapper_send_vs_config()175 void hal_wrapper_send_vs_config() {
176 STLOG_HAL_V("%s - Enter", __func__);
177 set_ready(0);
178
179 if (!HalSendDownstreamTimer(mHalHandle, nciPropGetFwDbgTracesConfig,
180 sizeof(nciPropGetFwDbgTracesConfig), 500)) {
181 STLOG_HAL_E("%s - SendDownstream failed", __func__);
182 }
183 mReadFwConfigDone = true;
184 wait_ready();
185 }
186
hal_wrapper_send_config()187 void hal_wrapper_send_config() {
188 hal_wrapper_send_core_config_prop();
189 mHalWrapperState = HAL_WRAPPER_STATE_PROP_CONFIG;
190 hal_wrapper_send_vs_config();
191 }
192
hal_wrapper_factoryReset()193 void hal_wrapper_factoryReset() {
194 mfactoryReset = true;
195 STLOG_HAL_V("%s - mfactoryReset = %d", __func__, mfactoryReset);
196 }
197
hal_wrapper_update_complete()198 void hal_wrapper_update_complete() {
199 STLOG_HAL_V("%s ", __func__);
200 mHalWrapperCallback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
201 mHalWrapperState = HAL_WRAPPER_STATE_OPEN_CPLT;
202 }
halWrapperDataCallback(uint16_t data_len,uint8_t * p_data)203 void halWrapperDataCallback(uint16_t data_len, uint8_t* p_data) {
204 uint8_t propNfcModeSetCmdOn[] = {0x2f, 0x02, 0x02, 0x02, 0x01};
205 uint8_t coreInitCmd[] = {0x20, 0x01, 0x02, 0x00, 0x00};
206 uint8_t coreResetCmd[] = {0x20, 0x00, 0x01, 0x01};
207 unsigned long num = 0;
208 unsigned long swp_log = 0;
209 unsigned long rf_log = 0;
210 int nciPropEnableFwDbgTraces_size = sizeof(nciPropEnableFwDbgTraces);
211
212 switch (mHalWrapperState) {
213 case HAL_WRAPPER_STATE_CLOSED: // 0
214 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_CLOSED", __func__);
215 break;
216 case HAL_WRAPPER_STATE_OPEN: // 1
217 // CORE_RESET_NTF
218 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_OPEN", __func__);
219
220 if ((p_data[0] == 0x60) && (p_data[1] == 0x00)) {
221 mIsActiveRW = false;
222 mFwUpdateTaskMask = ft_cmd_HwReset(p_data, &mClfMode);
223
224 if (mfactoryReset == true) {
225 STLOG_HAL_V(
226 "%s - first boot after factory reset detected - start FW update",
227 __func__);
228 if ((mFwUpdateResMask & FW_PATCH_AVAILABLE) &&
229 (mFwUpdateResMask & FW_CUSTOM_PARAM_AVAILABLE)) {
230 mFwUpdateTaskMask = FW_UPDATE_NEEDED | CONF_UPDATE_NEEDED;
231 mfactoryReset = false;
232 }
233 }
234 STLOG_HAL_V(
235 "%s - mFwUpdateTaskMask = %d, mClfMode = %d, mRetryFwDwl = %d",
236 __func__, mFwUpdateTaskMask, mClfMode, mRetryFwDwl);
237 // CLF in MODE LOADER & Update needed.
238 if (mClfMode == FT_CLF_MODE_LOADER) {
239 HalSendDownstreamStopTimer(mHalHandle);
240 STLOG_HAL_V("%s --- CLF mode is LOADER ---", __func__);
241
242 if (mRetryFwDwl == 0) {
243 STLOG_HAL_V(
244 "%s - Reached maximum nb of retries, FW update failed, exiting",
245 __func__);
246 mHalWrapperCallback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
247 I2cCloseLayer();
248 } else {
249 if (((p_data[3] == 0x01) && (p_data[8] == HW_ST54L)) ||
250 ((p_data[2] == 0x41) && (p_data[3] == 0xA2))) { // ST54L
251 FwUpdateHandler(mHalHandle, data_len, p_data);
252 } else {
253 STLOG_HAL_V("%s - Send APDU_GET_ATR_CMD", __func__);
254 mRetryFwDwl--;
255 if (!HalSendDownstreamTimer(mHalHandle, ApduGetAtr,
256 sizeof(ApduGetAtr),
257 FW_TIMER_DURATION)) {
258 STLOG_HAL_E("%s - SendDownstream failed", __func__);
259 }
260 }
261 mHalWrapperState = HAL_WRAPPER_STATE_UPDATE;
262 }
263 } else if (mFwUpdateTaskMask == 0 || mRetryFwDwl == 0) {
264 STLOG_HAL_V("%s - Proceeding with normal startup", __func__);
265 if (p_data[3] == 0x01) {
266 // Normal mode, start HAL
267 mHalWrapperCallback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
268 mHalWrapperState = HAL_WRAPPER_STATE_OPEN_CPLT;
269 } else {
270 // No more retries or CLF not in correct mode
271 mHalWrapperCallback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
272 }
273 // CLF in MODE ROUTER & Update needed.
274 } else if (mClfMode == FT_CLF_MODE_ROUTER) {
275 if ((mFwUpdateTaskMask & FW_UPDATE_NEEDED) &&
276 (mFwUpdateResMask & FW_PATCH_AVAILABLE)) {
277 STLOG_HAL_V(
278 "%s - CLF in ROUTER mode, FW update needed, try upgrade FW -",
279 __func__);
280 mRetryFwDwl--;
281
282 if (!HalSendDownstream(mHalHandle, coreResetCmd,
283 sizeof(coreResetCmd))) {
284 STLOG_HAL_E("%s - SendDownstream failed", __func__);
285 }
286 mHalWrapperState = HAL_WRAPPER_STATE_EXIT_HIBERNATE_INTERNAL;
287 } else if ((mFwUpdateTaskMask & CONF_UPDATE_NEEDED) &&
288 (mFwUpdateResMask & FW_CUSTOM_PARAM_AVAILABLE)) {
289 if (!HalSendDownstream(mHalHandle, coreResetCmd,
290 sizeof(coreResetCmd))) {
291 STLOG_HAL_E("%s - SendDownstream failed", __func__);
292 }
293 mHalWrapperState = HAL_WRAPPER_STATE_APPLY_CUSTOM_PARAM;
294 } else if ((mFwUpdateTaskMask & UWB_CONF_UPDATE_NEEDED) &&
295 (mFwUpdateResMask & FW_UWB_PARAM_AVAILABLE)) {
296 if (!HalSendDownstream(mHalHandle, coreResetCmd,
297 sizeof(coreResetCmd))) {
298 STLOG_HAL_E("%s - SendDownstream failed", __func__);
299 }
300 mHalWrapperState = HAL_WRAPPER_STATE_APPLY_UWB_PARAM;
301 }
302 }
303 } else {
304 mHalWrapperDataCallback(data_len, p_data);
305 }
306 break;
307 case HAL_WRAPPER_STATE_OPEN_CPLT: // 2
308 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_OPEN_CPLT",
309 __func__);
310 // CORE_INIT_RSP
311 if ((p_data[0] == 0x40) && (p_data[1] == 0x01)) {
312 } else if ((p_data[0] == 0x60) && (p_data[1] == 0x06)) {
313 STLOG_HAL_V("%s - Sending PROP_NFC_MODE_SET_CMD", __func__);
314 // Send PROP_NFC_MODE_SET_CMD(ON)
315 if (!HalSendDownstreamTimer(mHalHandle, propNfcModeSetCmdOn,
316 sizeof(propNfcModeSetCmdOn), 100)) {
317 STLOG_HAL_E("NFC-NCI HAL: %s HalSendDownstreamTimer failed",
318 __func__);
319 }
320 mHalWrapperState = HAL_WRAPPER_STATE_NFC_ENABLE_ON;
321 } else {
322 mHalWrapperDataCallback(data_len, p_data);
323 }
324 break;
325
326 case HAL_WRAPPER_STATE_NFC_ENABLE_ON: // 3
327 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_NFC_ENABLE_ON",
328 __func__);
329 // PROP_NFC_MODE_SET_RSP
330 if ((p_data[0] == 0x4f) && (p_data[1] == 0x02)) {
331 // DO nothing: wait for core_reset_ntf or timer timeout
332 }
333 // CORE_RESET_NTF
334 else if ((p_data[0] == 0x60) && (p_data[1] == 0x00)) {
335 // Stop timer
336 HalSendDownstreamStopTimer(mHalHandle);
337 if (forceRecover == true) {
338 forceRecover = false;
339 mHalWrapperDataCallback(data_len, p_data);
340 break;
341 }
342
343 // Send CORE_INIT_CMD
344 STLOG_HAL_V("%s - Sending CORE_INIT_CMD", __func__);
345 if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
346 STLOG_HAL_E("NFC-NCI HAL: %s SendDownstream failed", __func__);
347 }
348 }
349 // CORE_INIT_RSP
350 else if ((p_data[0] == 0x40) && (p_data[1] == 0x01)) {
351 STLOG_HAL_D("%s - NFC mode enabled", __func__);
352 // Do we need to lend a credit ?
353 if (p_data[13] == 0x00) {
354 STLOG_HAL_D("%s - 1 credit lent", __func__);
355 p_data[13] = 0x01;
356 mHciCreditLent = true;
357 }
358
359 mHalWrapperState = HAL_WRAPPER_STATE_READY;
360 mHalWrapperDataCallback(data_len, p_data);
361 }
362 break;
363
364 case HAL_WRAPPER_STATE_PROP_CONFIG: // 4
365 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_PROP_CONFIG",
366 __func__);
367 // CORE_SET_CONFIG_RSP
368 if ((p_data[0] == 0x40) && (p_data[1] == 0x02)) {
369 HalSendDownstreamStopTimer(mHalHandle);
370 set_ready(1);
371
372 STLOG_HAL_V("%s - Received config RSP, read FW dDBG config", __func__);
373 } else if (mHciCreditLent && (p_data[0] == 0x60) && (p_data[1] == 0x06)) {
374 // CORE_CONN_CREDITS_NTF
375 if (p_data[4] == 0x01) { // HCI connection
376 mHciCreditLent = false;
377 STLOG_HAL_D("%s - credit returned", __func__);
378 if (p_data[5] == 0x01) {
379 // no need to send this.
380 break;
381 } else {
382 if (p_data[5] != 0x00 && p_data[5] != 0xFF) {
383 // send with 1 less
384 p_data[5]--;
385 }
386 }
387 }
388 mHalWrapperDataCallback(data_len, p_data);
389 } else if (p_data[0] == 0x4f) {
390 // PROP_RSP
391 if (mReadFwConfigDone == true) {
392 mReadFwConfigDone = false;
393 HalSendDownstreamStopTimer(mHalHandle);
394 set_ready(1);
395 // NFC_STATUS_OK
396 if (p_data[3] == 0x00) {
397 bool confNeeded = false;
398 bool firmware_debug_enabled =
399 property_get_int32("persist.vendor.nfc.firmware_debug_enabled", 0);
400
401 // Check if FW DBG shall be set
402 if (GetNumValue(NAME_STNFC_FW_DEBUG_ENABLED, &num, sizeof(num)) ||
403 isDebuggable || sEnableFwLog) {
404 if (firmware_debug_enabled || sEnableFwLog) {
405 num = 1;
406 swp_log = 30;
407 rf_log = 15;
408 }
409 if (num == 1) {
410 GetNumValue(NAME_STNFC_FW_SWP_LOG_SIZE, &swp_log,
411 sizeof(swp_log));
412 GetNumValue(NAME_STNFC_FW_RF_LOG_SIZE, &rf_log, sizeof(rf_log));
413 }
414 // limit swp and rf payload length between 4 and 30.
415 if (swp_log > 30)
416 swp_log = 30;
417 else if (swp_log < 4)
418 swp_log = 4;
419
420 if (rf_log > 30)
421 rf_log = 30;
422 else if (rf_log < 4)
423 rf_log = 4;
424
425 if ((rf_log || swp_log) &&
426 ((p_data[15] != rf_log) || (p_data[17] != swp_log))) {
427 STLOG_HAL_D("%s - FW DBG payload traces changes needed",
428 __func__);
429 confNeeded = true;
430 }
431
432 // If conf file indicate set needed and not yet enabled
433 if ((num == 1) && (p_data[7] == 0x00)) {
434 STLOG_HAL_D("%s - FW DBG traces enabling needed", __func__);
435 nciPropEnableFwDbgTraces[9] = 0x01;
436 confNeeded = true;
437 } else if ((num == 0) && (p_data[7] == 0x01)) {
438 STLOG_HAL_D("%s - FW DBG traces disabling needed", __func__);
439 nciPropEnableFwDbgTraces[9] = 0x00;
440 confNeeded = true;
441 } else {
442 STLOG_HAL_D(
443 "%s - No FW DBG traces enable/disable change needed",
444 __func__);
445 }
446
447 if (data_len < 9 || p_data[6] == 0 || p_data[6] < (data_len - 7)
448 || p_data[6] > (sizeof(nciPropEnableFwDbgTraces) - 9)) {
449 if (confNeeded) {
450 android_errorWriteLog(0x534e4554, "169328517");
451 confNeeded = false;
452 }
453 }
454
455 if (confNeeded) {
456 memcpy(nciPropEnableFwDbgTraces, nciHeaderPropSetConfig, 9);
457 memcpy(&nciPropEnableFwDbgTraces[10], &p_data[8],
458 p_data[6] - 1);
459 if (rf_log || swp_log) {
460 nciPropEnableFwDbgTraces[9] = (uint8_t)num;
461 nciPropEnableFwDbgTraces[17] = (uint8_t)rf_log;
462 nciPropEnableFwDbgTraces[19] = (uint8_t)swp_log;
463 }
464 if ((9 + p_data[6]) < sizeof(nciPropEnableFwDbgTraces)) {
465 nciPropEnableFwDbgTraces_size = 9 + p_data[6];
466 }
467
468 confNeeded = false;
469
470 if (!HalSendDownstream(mHalHandle, nciPropEnableFwDbgTraces,
471 nciPropEnableFwDbgTraces_size)) {
472 STLOG_HAL_E("%s - SendDownstream failed", __func__);
473 }
474 mHalWrapperState = HAL_WRAPPER_STATE_APPLY_PROP_CONFIG;
475 break;
476 }
477 }
478 }
479 }
480 GetNumValue(NAME_STNFC_REMOTE_FIELD_TIMER, &hal_field_timer,
481 sizeof(hal_field_timer));
482 STLOG_HAL_D("%s - hal_field_timer = %lu", __func__, hal_field_timer);
483 // Exit state, all processing done
484 mHalWrapperCallback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
485 mHalWrapperState = HAL_WRAPPER_STATE_READY;
486 }
487 break;
488
489 case HAL_WRAPPER_STATE_READY: // 5
490 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_READY", __func__);
491 if (!((p_data[0] == 0x60) && (p_data[3] == 0xa0))) {
492 if (mHciCreditLent && (p_data[0] == 0x60) && (p_data[1] == 0x06)) {
493 if (p_data[4] == 0x01) { // HCI connection
494 mHciCreditLent = false;
495 STLOG_HAL_D("%s - credit returned", __func__);
496 if (p_data[5] == 0x01) {
497 // no need to send this.
498 break;
499 } else {
500 if (p_data[5] != 0x00 && p_data[5] != 0xFF) {
501 // send with 1 less
502 p_data[5]--;
503 }
504 }
505 }
506 } else if ((p_data[0] == 0x61) && (p_data[1] == 0x07)) {
507 // RF_FIELD_INFO_NTF
508 if (p_data[3] == 0x01) { // field on
509 // start timer
510 if (hal_field_timer) {
511 mFieldInfoTimerStarted = true;
512 HalSendDownstreamTimer(mHalHandle, 20000);
513 }
514 } else if (p_data[3] == 0x00) {
515 if (mFieldInfoTimerStarted) {
516 HalSendDownstreamStopTimer(mHalHandle);
517 mFieldInfoTimerStarted = false;
518 }
519 }
520 } else if ((p_data[0] == 0x6f) && (p_data[1] == 0x05)) {
521 (void)pthread_mutex_lock(&mutex_activerw);
522 // start timer
523 mTimerStarted = true;
524 HalSendDownstreamTimer(mHalHandle, 5000);
525 mIsActiveRW = true;
526 (void)pthread_mutex_unlock(&mutex_activerw);
527 } else if ((p_data[0] == 0x6f) && (p_data[1] == 0x06)) {
528 (void)pthread_mutex_lock(&mutex_activerw);
529 // stop timer
530 if (mTimerStarted) {
531 HalSendDownstreamStopTimer(mHalHandle);
532 mTimerStarted = false;
533 }
534 if(mIsActiveRW == true) {
535 mIsActiveRW = false;
536 } else {
537 mError_count ++;
538 STLOG_HAL_E("Error Act -> Act count=%d", mError_count);
539 if(mError_count > 20) {
540 mError_count = 0;
541 STLOG_HAL_E("NFC Recovery Start");
542 mTimerStarted = true;
543 HalSendDownstreamTimer(mHalHandle, 1);
544 }
545 }
546 (void)pthread_mutex_unlock(&mutex_activerw);
547 } else if (((p_data[0] == 0x61) && (p_data[1] == 0x05)) ||
548 ((p_data[0] == 0x61) && (p_data[1] == 0x03))) {
549 mError_count = 0;
550 // stop timer
551 if (mFieldInfoTimerStarted) {
552 HalSendDownstreamStopTimer(mHalHandle);
553 mFieldInfoTimerStarted = false;
554 }
555 if (mTimerStarted) {
556 HalSendDownstreamStopTimer(mHalHandle);
557 mTimerStarted = false;
558 }
559 } else if (data_len >= 4 && p_data[0] == 0x60 && p_data[1] == 0x07) {
560 if (p_data[3] == 0xE1) {
561 // Core Generic Error - Buffer Overflow Ntf - Restart all
562 STLOG_HAL_E("Core Generic Error - restart");
563 p_data[0] = 0x60;
564 p_data[1] = 0x00;
565 p_data[2] = 0x03;
566 p_data[3] = 0xE1;
567 p_data[4] = 0x00;
568 p_data[5] = 0x00;
569 data_len = 0x6;
570 } else if (p_data[3] == 0xE6) {
571 unsigned long hal_ctrl_clk = 0;
572 GetNumValue(NAME_STNFC_CONTROL_CLK, &hal_ctrl_clk,
573 sizeof(hal_ctrl_clk));
574 if (hal_ctrl_clk) {
575 STLOG_HAL_E("%s - Clock Error - restart", __func__);
576 // Core Generic Error
577 p_data[0] = 0x60;
578 p_data[1] = 0x00;
579 p_data[2] = 0x03;
580 p_data[3] = 0xE6;
581 p_data[4] = 0x00;
582 p_data[5] = 0x00;
583 data_len = 0x6;
584 }
585 } else if (p_data[3] == 0xA1) {
586 if (mFieldInfoTimerStarted) {
587 HalSendDownstreamStopTimer(mHalHandle);
588 mFieldInfoTimerStarted = false;
589 }
590 }
591 }
592 mHalWrapperDataCallback(data_len, p_data);
593 } else {
594 STLOG_HAL_V("%s - Core reset notification - Nfc mode ", __func__);
595 }
596 break;
597
598 case HAL_WRAPPER_STATE_CLOSING: // 6
599 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_CLOSING",
600 __func__);
601 hal_fd_close();
602 if ((p_data[0] == 0x4f) && (p_data[1] == 0x02)) {
603 // intercept this expected message, don t forward.
604 mHalWrapperState = HAL_WRAPPER_STATE_CLOSED;
605 } else {
606 mHalWrapperDataCallback(data_len, p_data);
607 }
608 break;
609
610 case HAL_WRAPPER_STATE_EXIT_HIBERNATE_INTERNAL: // 6
611 STLOG_HAL_V(
612 "%s - mHalWrapperState = HAL_WRAPPER_STATE_EXIT_HIBERNATE_INTERNAL",
613 __func__);
614 ExitHibernateHandler(mHalHandle, data_len, p_data);
615 break;
616
617 case HAL_WRAPPER_STATE_UPDATE: // 7
618 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_UPDATE", __func__);
619 FwUpdateHandler(mHalHandle, data_len, p_data);
620 break;
621 case HAL_WRAPPER_STATE_APPLY_CUSTOM_PARAM: // 8
622 STLOG_HAL_V(
623 "%s - mHalWrapperState = HAL_WRAPPER_STATE_APPLY_CUSTOM_PARAM",
624 __func__);
625 ApplyCustomParamHandler(mHalHandle, data_len, p_data);
626 break;
627 case HAL_WRAPPER_STATE_APPLY_UWB_PARAM: // 9
628 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_APPLY_UWB_PARAM",
629 __func__);
630 ApplyUwbParamHandler(mHalHandle, data_len, p_data);
631 break;
632 case HAL_WRAPPER_STATE_SET_ACTIVERW_TIMER: // 10
633 (void)pthread_mutex_lock(&mutex_activerw);
634 if (mIsActiveRW == true) {
635 STLOG_HAL_D(
636 "%s - mHalWrapperState = "
637 "HAL_WRAPPER_STATE_SET_ACTIVERW_TIMER",
638 __func__);
639 // start timer
640 mTimerStarted = true;
641 HalSendDownstreamTimer(mHalHandle, 5000);
642 // Chip state should back to Active
643 // at screen off state.
644 }
645 (void)pthread_mutex_unlock(&mutex_activerw);
646 mHalWrapperState = HAL_WRAPPER_STATE_READY;
647 mHalWrapperDataCallback(data_len, p_data);
648 break;
649
650 case HAL_WRAPPER_STATE_APPLY_PROP_CONFIG:
651 STLOG_HAL_V("%s - mHalWrapperState = HAL_WRAPPER_STATE_APPLY_PROP_CONFIG",
652 __func__);
653 if (p_data[0] == 0x4f) {
654 I2cResetPulse();
655 } else if ((p_data[0] == 0x60) && (p_data[1] == 0x00)) {
656 // Send CORE_INIT_CMD
657 STLOG_HAL_D("%s - Sending CORE_INIT_CMD", __func__);
658 if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
659 STLOG_HAL_E("NFC-NCI HAL: %s SendDownstream failed", __func__);
660 }
661 }
662 // CORE_INIT_RSP
663 else if ((p_data[0] == 0x40) && (p_data[1] == 0x01)) {
664 // Exit state, all processing done
665 mHalWrapperCallback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
666 mHalWrapperState = HAL_WRAPPER_STATE_READY;
667 }
668 break;
669 case HAL_WRAPPER_STATE_RECOVERY:
670 break;
671 }
672 }
673
halWrapperCallback(uint8_t event,uint8_t event_status)674 static void halWrapperCallback(uint8_t event, __attribute__((unused))uint8_t event_status) {
675 uint8_t coreInitCmd[] = {0x20, 0x01, 0x02, 0x00, 0x00};
676 uint8_t rfDeactivateCmd[] = {0x21, 0x06, 0x01, 0x00};
677 uint8_t p_data[6];
678 uint16_t data_len;
679
680 switch (mHalWrapperState) {
681 case HAL_WRAPPER_STATE_CLOSING:
682 if (event == HAL_WRAPPER_TIMEOUT_EVT) {
683 STLOG_HAL_D("NFC-NCI HAL: %s Timeout. Close anyway", __func__);
684 HalSendDownstreamStopTimer(mHalHandle);
685 hal_fd_close();
686 mHalWrapperState = HAL_WRAPPER_STATE_CLOSED;
687 return;
688 }
689 break;
690
691 case HAL_WRAPPER_STATE_OPEN:
692 if (event == HAL_WRAPPER_TIMEOUT_EVT) {
693 STLOG_HAL_D("NFC-NCI HAL: %s Timeout accessing the CLF.", __func__);
694 HalSendDownstreamStopTimer(mHalHandle);
695 I2cRecovery();
696 abort(); // TODO: fix it when we have a better recovery method.
697 return;
698 }
699 break;
700
701 case HAL_WRAPPER_STATE_CLOSED:
702 if (event == HAL_WRAPPER_TIMEOUT_EVT) {
703 STLOG_HAL_D("NFC-NCI HAL: %s Timeout. Close anyway", __func__);
704 HalSendDownstreamStopTimer(mHalHandle);
705 return;
706 }
707 break;
708
709 case HAL_WRAPPER_STATE_UPDATE:
710 if (event == HAL_WRAPPER_TIMEOUT_EVT) {
711 STLOG_HAL_E("%s - Timer for FW update procedure timeout, retry",
712 __func__);
713 abort(); // TODO: fix it when we have a better recovery method.
714 HalSendDownstreamStopTimer(mHalHandle);
715 resetHandlerState();
716 I2cResetPulse();
717 mHalWrapperState = HAL_WRAPPER_STATE_OPEN;
718 }
719 break;
720
721 case HAL_WRAPPER_STATE_NFC_ENABLE_ON:
722 if (event == HAL_WRAPPER_TIMEOUT_EVT) {
723 // timeout
724 // Send CORE_INIT_CMD
725 STLOG_HAL_V("%s - Sending CORE_INIT_CMD", __func__);
726 if (!HalSendDownstream(mHalHandle, coreInitCmd, sizeof(coreInitCmd))) {
727 STLOG_HAL_E("NFC-NCI HAL: %s SendDownstream failed", __func__);
728 }
729 return;
730 }
731 break;
732 case HAL_WRAPPER_STATE_PROP_CONFIG:
733 if (event == HAL_WRAPPER_TIMEOUT_EVT) {
734 STLOG_HAL_E("%s - Timer when sending conf parameters, retry", __func__);
735 abort(); // TODO: fix it when we have a better recovery method.
736 HalSendDownstreamStopTimer(mHalHandle);
737 resetHandlerState();
738 I2cResetPulse();
739 mHalWrapperState = HAL_WRAPPER_STATE_OPEN;
740 }
741 break;
742
743 case HAL_WRAPPER_STATE_READY:
744 if (event == HAL_WRAPPER_TIMEOUT_EVT) {
745 if (mTimerStarted || mFieldInfoTimerStarted) {
746 STLOG_HAL_E("NFC-NCI HAL: %s Timeout.. Recover!", __func__);
747 STLOG_HAL_E("%s mIsActiveRW = %d", __func__, mIsActiveRW);
748 HalSendDownstreamStopTimer(mHalHandle);
749 mTimerStarted = false;
750 mFieldInfoTimerStarted = false;
751 // forceRecover = true;
752 resetHandlerState();
753 if (!HalSendDownstream(mHalHandle, rfDeactivateCmd,
754 sizeof(rfDeactivateCmd))) {
755 STLOG_HAL_E("%s - SendDownstream failed", __func__);
756 }
757 usleep(10000);
758 // Core Generic Error
759
760 p_data[0] = 0x60;
761 p_data[1] = 0x00;
762 p_data[2] = 0x03;
763 p_data[3] = 0xAA;
764 p_data[4] = 0x00;
765 p_data[5] = 0x00;
766 data_len = 0x6;
767 mHalWrapperDataCallback(data_len, p_data);
768 mHalWrapperState = HAL_WRAPPER_STATE_RECOVERY;
769 }
770 return;
771 }
772 break;
773
774 default:
775 break;
776 }
777
778 mHalWrapperCallback(event, event_status);
779 }
780
781 /*******************************************************************************
782 **
783 ** Function nfc_set_state
784 **
785 ** Description Set the state of NFC stack
786 **
787 ** Returns void
788 **
789 *******************************************************************************/
hal_wrapper_set_state(hal_wrapper_state_e new_wrapper_state)790 void hal_wrapper_set_state(hal_wrapper_state_e new_wrapper_state) {
791 ALOGD("nfc_set_state %d->%d", mHalWrapperState, new_wrapper_state);
792
793 mHalWrapperState = new_wrapper_state;
794 }
795
796 /*******************************************************************************
797 **
798 ** Function hal_wrapper_setFwLogging
799 **
800 ** Description Enable the FW log by hte GUI if needed.
801 **
802 ** Returns void
803 **
804 *******************************************************************************/
hal_wrapper_setFwLogging(bool enable)805 void hal_wrapper_setFwLogging(bool enable) {
806 ALOGD("%s : enable = %d", __func__, enable);
807
808 sEnableFwLog = enable;
809 }
810