• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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