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