1 /******************************************************************************
2  *
3  *  Copyright (C) 2012 Broadcom Corporation
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 /******************************************************************************
20  *
21  *  HAL Adaptation Interface (HAI). This interface regulates the interaction
22  *  between standard Android HAL and Broadcom-specific HAL.  It adapts
23  *  Broadcom-specific features to the Android framework.
24  *
25  ******************************************************************************/
26 #define LOG_TAG "NfcNciHal"
27 #include "HalAdaptation.h"
28 #include <cutils/properties.h>
29 #include <errno.h>
30 #include <pthread.h>
31 #include "SyncEvent.h"
32 #include "_OverrideLog.h"
33 #include "android_logmsg.h"
34 #include "buildcfg.h"
35 #include "config.h"
36 #include "nfc_hal_int.h"
37 #include "nfc_hal_post_reset.h"
38 extern void delete_hal_non_volatile_store(bool forceDelete);
39 extern void verify_hal_non_volatile_store();
40 extern void resetConfig();
41 extern "C" {
42 #include "userial.h"
43 }
44 
45 extern void configureCrystalFrequency();
46 
47 ///////////////////////////////////////
48 // private declaration, definition
49 
50 static nfc_stack_callback_t* gAndroidHalCallback = NULL;
51 static nfc_stack_data_callback_t* gAndroidHalDataCallback = NULL;
52 static SyncEvent gOpenCompletedEvent;
53 static SyncEvent gPostInitCompletedEvent;
54 static SyncEvent gCloseCompletedEvent;
55 
56 uint32_t ScrProtocolTraceFlag = SCR_PROTO_TRACE_ALL;  // 0x017F00;
57 
58 static void BroadcomHalCallback(uint8_t event, tHAL_NFC_STATUS status);
59 static void BroadcomHalDataCallback(uint16_t data_len, uint8_t* p_data);
60 
61 static bool isColdBoot = true;
62 
63 extern tNFC_HAL_CFG* p_nfc_hal_cfg;
64 extern const uint8_t nfca_version_string[];
65 extern const uint8_t nfa_version_string[];
66 
67 tNFC_HAL_DM_PRE_SET_MEM nfc_hal_pre_set_mem_20795a1[] = {
68     {0x0016403c, 0x00000008},
69     {0x0016403c, 0x00000000},
70     {0x0014008c, 0x00000001},
71     {0, 0}};
72 
73 extern tNFC_HAL_DM_PRE_SET_MEM* p_nfc_hal_dm_pre_set_mem;
74 
75 ///////////////////////////////////////
76 
HaiInitializeLibrary(const bcm2079x_dev_t * device)77 int HaiInitializeLibrary(const bcm2079x_dev_t* device) {
78   ALOGD("%s: enter", __func__);
79   ALOGE("%s: ver=%s nfa=%s", __func__, nfca_version_string, nfa_version_string);
80   int retval = EACCES;
81   unsigned long freq = 0;
82   unsigned long num = 0;
83   char temp[120];
84   int8_t prop_value;
85   uint8_t logLevel = 0;
86 
87   logLevel = InitializeGlobalAppLogLevel();
88 
89   if (GetNumValue(NAME_GLOBAL_RESET, &num, sizeof(num))) {
90     if (num == 1) {
91       // Send commands to disable boc
92       p_nfc_hal_dm_pre_set_mem = nfc_hal_pre_set_mem_20795a1;
93     }
94   }
95 
96   configureCrystalFrequency();
97   verify_hal_non_volatile_store();
98   if (GetNumValue(NAME_PRESERVE_STORAGE, (char*)&num, sizeof(num)) &&
99       (num == 1))
100     ALOGD("%s: preserve HAL NV store", __func__);
101   else {
102     delete_hal_non_volatile_store(false);
103   }
104 
105   if (GetNumValue(NAME_USE_RAW_NCI_TRACE, &num, sizeof(num))) {
106     if (num == 1) {
107       // display protocol traces in raw format
108       ProtoDispAdapterUseRawOutput(TRUE);
109     }
110   }
111 
112   // Initialize protocol logging level
113   InitializeProtocolLogLevel();
114 
115   tUSERIAL_OPEN_CFG cfg;
116   struct tUART_CONFIG uart;
117 
118   if (GetStrValue(NAME_UART_PARITY, temp, sizeof(temp))) {
119     if (strcmp(temp, "even") == 0)
120       uart.m_iParity = USERIAL_PARITY_EVEN;
121     else if (strcmp(temp, "odd") == 0)
122       uart.m_iParity = USERIAL_PARITY_ODD;
123     else if (strcmp(temp, "none") == 0)
124       uart.m_iParity = USERIAL_PARITY_NONE;
125   } else
126     uart.m_iParity = USERIAL_PARITY_NONE;
127 
128   if (GetStrValue(NAME_UART_STOPBITS, temp, sizeof(temp))) {
129     if (strcmp(temp, "1") == 0)
130       uart.m_iStopbits = USERIAL_STOPBITS_1;
131     else if (strcmp(temp, "2") == 0)
132       uart.m_iStopbits = USERIAL_STOPBITS_2;
133     else if (strcmp(temp, "1.5") == 0)
134       uart.m_iStopbits = USERIAL_STOPBITS_1_5;
135   } else if (GetNumValue(NAME_UART_STOPBITS, &num, sizeof(num))) {
136     if (num == 1)
137       uart.m_iStopbits = USERIAL_STOPBITS_1;
138     else if (num == 2)
139       uart.m_iStopbits = USERIAL_STOPBITS_2;
140   } else
141     uart.m_iStopbits = USERIAL_STOPBITS_1;
142 
143   if (GetNumValue(NAME_UART_DATABITS, &num, sizeof(num))) {
144     if (5 <= num && num <= 8) uart.m_iDatabits = (1 << (num + 1));
145   } else
146     uart.m_iDatabits = USERIAL_DATABITS_8;
147 
148   if (GetNumValue(NAME_UART_BAUD, &num, sizeof(num))) {
149     if (num == 300)
150       uart.m_iBaudrate = USERIAL_BAUD_300;
151     else if (num == 600)
152       uart.m_iBaudrate = USERIAL_BAUD_600;
153     else if (num == 1200)
154       uart.m_iBaudrate = USERIAL_BAUD_1200;
155     else if (num == 2400)
156       uart.m_iBaudrate = USERIAL_BAUD_2400;
157     else if (num == 9600)
158       uart.m_iBaudrate = USERIAL_BAUD_9600;
159     else if (num == 19200)
160       uart.m_iBaudrate = USERIAL_BAUD_19200;
161     else if (num == 57600)
162       uart.m_iBaudrate = USERIAL_BAUD_57600;
163     else if (num == 115200)
164       uart.m_iBaudrate = USERIAL_BAUD_115200;
165     else if (num == 230400)
166       uart.m_iBaudrate = USERIAL_BAUD_230400;
167     else if (num == 460800)
168       uart.m_iBaudrate = USERIAL_BAUD_460800;
169     else if (num == 921600)
170       uart.m_iBaudrate = USERIAL_BAUD_921600;
171   } else if (GetStrValue(NAME_UART_BAUD, temp, sizeof(temp))) {
172     if (strcmp(temp, "auto") == 0) uart.m_iBaudrate = USERIAL_BAUD_AUTO;
173   } else
174     uart.m_iBaudrate = USERIAL_BAUD_115200;
175 
176   memset(&cfg, 0, sizeof(tUSERIAL_OPEN_CFG));
177   cfg.fmt = uart.m_iDatabits | uart.m_iParity | uart.m_iStopbits;
178   cfg.baud = uart.m_iBaudrate;
179 
180   ALOGD("%s: uart config=0x%04x, %d\n", __func__, cfg.fmt, cfg.baud);
181   USERIAL_Init(&cfg);
182 
183   if (GetNumValue(NAME_NFCC_ENABLE_TIMEOUT, &num, sizeof(num))) {
184     p_nfc_hal_cfg->nfc_hal_nfcc_enable_timeout = num;
185   }
186 
187   if (GetNumValue(NAME_NFA_MAX_EE_SUPPORTED, &num, sizeof(num)) && num == 0) {
188     // Since NFA_MAX_EE_SUPPORTED is explicetly set to 0, no UICC support is
189     // needed.
190     p_nfc_hal_cfg->nfc_hal_hci_uicc_support = 0;
191   }
192 
193   prop_value = property_get_bool("nfc.bcm2079x.isColdboot", 0);
194   if (prop_value) {
195     isColdBoot = true;
196     property_set("nfc.bcm2079x.isColdboot", "0");
197   }
198   // Set 'first boot' flag based on static variable that will get set to false
199   // after the stack has first initialized the EE.
200   p_nfc_hal_cfg->nfc_hal_first_boot = isColdBoot ? TRUE : FALSE;
201 
202   HAL_NfcInitialize();
203   HAL_NfcSetTraceLevel(logLevel);  // Initialize HAL's logging level
204 
205   retval = 0;
206   ALOGD("%s: exit %d", __func__, retval);
207   return retval;
208 }
209 
HaiTerminateLibrary()210 int HaiTerminateLibrary() {
211   int retval = EACCES;
212   ALOGD("%s: enter", __func__);
213 
214   HAL_NfcTerminate();
215   gAndroidHalCallback = NULL;
216   gAndroidHalDataCallback = NULL;
217   GKI_shutdown();
218   resetConfig();
219   retval = 0;
220   ALOGD("%s: exit %d", __func__, retval);
221   return retval;
222 }
223 
HaiOpen(const bcm2079x_dev_t * device,nfc_stack_callback_t * halCallbackFunc,nfc_stack_data_callback_t * halDataCallbackFunc)224 int HaiOpen(const bcm2079x_dev_t* device, nfc_stack_callback_t* halCallbackFunc,
225             nfc_stack_data_callback_t* halDataCallbackFunc) {
226   ALOGD("%s: enter", __func__);
227   int retval = EACCES;
228 
229   gAndroidHalCallback = halCallbackFunc;
230   gAndroidHalDataCallback = halDataCallbackFunc;
231 
232   SyncEventGuard guard(gOpenCompletedEvent);
233   HAL_NfcOpen(BroadcomHalCallback, BroadcomHalDataCallback);
234   gOpenCompletedEvent.wait();
235 
236   retval = 0;
237   ALOGD("%s: exit %d", __func__, retval);
238   return retval;
239 }
240 
BroadcomHalCallback(uint8_t event,tHAL_NFC_STATUS status)241 void BroadcomHalCallback(uint8_t event, tHAL_NFC_STATUS status) {
242   ALOGD("%s: enter; event=0x%X", __func__, event);
243   switch (event) {
244     case HAL_NFC_OPEN_CPLT_EVT: {
245       ALOGD("%s: HAL_NFC_OPEN_CPLT_EVT; status=0x%X", __func__, status);
246       SyncEventGuard guard(gOpenCompletedEvent);
247       gOpenCompletedEvent.notifyOne();
248       break;
249     }
250 
251     case HAL_NFC_POST_INIT_CPLT_EVT: {
252       ALOGD("%s: HAL_NFC_POST_INIT_CPLT_EVT", __func__);
253       SyncEventGuard guard(gPostInitCompletedEvent);
254       gPostInitCompletedEvent.notifyOne();
255       break;
256     }
257 
258     case HAL_NFC_CLOSE_CPLT_EVT: {
259       ALOGD("%s: HAL_NFC_CLOSE_CPLT_EVT", __func__);
260       SyncEventGuard guard(gCloseCompletedEvent);
261       gCloseCompletedEvent.notifyOne();
262       break;
263     }
264 
265     case HAL_NFC_ERROR_EVT: {
266       ALOGD("%s: HAL_NFC_ERROR_EVT", __func__);
267       {
268         SyncEventGuard guard(gOpenCompletedEvent);
269         gOpenCompletedEvent.notifyOne();
270       }
271       {
272         SyncEventGuard guard(gPostInitCompletedEvent);
273         gPostInitCompletedEvent.notifyOne();
274       }
275       {
276         SyncEventGuard guard(gCloseCompletedEvent);
277         gCloseCompletedEvent.notifyOne();
278       }
279       break;
280     }
281   }
282   gAndroidHalCallback(event, status);
283   ALOGD("%s: exit; event=0x%X", __func__, event);
284 }
285 
BroadcomHalDataCallback(uint16_t data_len,uint8_t * p_data)286 void BroadcomHalDataCallback(uint16_t data_len, uint8_t* p_data) {
287   ALOGD("%s: enter; len=%u", __func__, data_len);
288   gAndroidHalDataCallback(data_len, p_data);
289 }
290 
HaiClose(const bcm2079x_dev_t * device)291 int HaiClose(const bcm2079x_dev_t* device) {
292   ALOGD("%s: enter", __func__);
293   int retval = EACCES;
294 
295   SyncEventGuard guard(gCloseCompletedEvent);
296   HAL_NfcClose();
297   gCloseCompletedEvent.wait();
298   retval = 0;
299   ALOGD("%s: exit %d", __func__, retval);
300   return retval;
301 }
302 
HaiCoreInitialized(const bcm2079x_dev_t * device,uint8_t * coreInitResponseParams)303 int HaiCoreInitialized(const bcm2079x_dev_t* device,
304                        uint8_t* coreInitResponseParams) {
305   ALOGD("%s: enter", __func__);
306   int retval = EACCES;
307 
308   SyncEventGuard guard(gPostInitCompletedEvent);
309   HAL_NfcCoreInitialized(0, coreInitResponseParams);
310   gPostInitCompletedEvent.wait();
311   retval = 0;
312   ALOGD("%s: exit %d", __func__, retval);
313   return retval;
314 }
315 
HaiWrite(const bcm2079x_dev_t * dev,uint16_t dataLen,const uint8_t * data)316 int HaiWrite(const bcm2079x_dev_t* dev, uint16_t dataLen, const uint8_t* data) {
317   ALOGD("%s: enter; len=%u", __func__, dataLen);
318   int retval = EACCES;
319 
320   HAL_NfcWrite(dataLen, const_cast<uint8_t*>(data));
321   retval = 0;
322   ALOGD("%s: exit %d", __func__, retval);
323   return retval;
324 }
325 
HaiPreDiscover(const bcm2079x_dev_t * device)326 int HaiPreDiscover(const bcm2079x_dev_t* device) {
327   ALOGD("%s: enter", __func__);
328   int retval = EACCES;
329 
330   // This function is a clear indication that the stack is initializing
331   // EE.  So we can reset the cold-boot flag here.
332   isColdBoot = false;
333   retval = HAL_NfcPreDiscover() ? 1 : 0;
334   ALOGD("%s: exit %d", __func__, retval);
335   return retval;
336 }
337 
HaiControlGranted(const bcm2079x_dev_t * device)338 int HaiControlGranted(const bcm2079x_dev_t* device) {
339   ALOGD("%s: enter", __func__);
340   int retval = EACCES;
341 
342   HAL_NfcControlGranted();
343   retval = 0;
344   ALOGD("%s: exit %d", __func__, retval);
345   return retval;
346 }
347 
HaiPowerCycle(const bcm2079x_dev_t * device)348 int HaiPowerCycle(const bcm2079x_dev_t* device) {
349   ALOGD("%s: enter", __func__);
350   int retval = EACCES;
351 
352   HAL_NfcPowerCycle();
353   retval = 0;
354   ALOGD("%s: exit %d", __func__, retval);
355   return retval;
356 }
357 
HaiGetMaxNfcee(const bcm2079x_dev_t * device,uint8_t * maxNfcee)358 int HaiGetMaxNfcee(const bcm2079x_dev_t* device, uint8_t* maxNfcee) {
359   ALOGD("%s: enter", __func__);
360   int retval = EACCES;
361 
362   // This function is a clear indication that the stack is initializing
363   // EE.  So we can reset the cold-boot flag here.
364   isColdBoot = false;
365 
366   if (maxNfcee) {
367     *maxNfcee = HAL_NfcGetMaxNfcee();
368     ALOGD("%s: max_ee from HAL to use %d", __func__, *maxNfcee);
369     retval = 0;
370   }
371   ALOGD("%s: exit %d", __func__, retval);
372   return retval;
373 }
374