1 /*
2  *    Copyright (C) 2013 SAMSUNG S.LSI
3  *
4  *   Licensed under the Apache License, Version 2.0 (the "License");
5  *   you may not use this file except in compliance with the License.
6  *   You may obtain a copy of the License at:
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *   Unless required by applicable law or agreed to in writing, software
11  *   distributed under the License is distributed on an "AS IS" BASIS,
12  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *   See the License for the specific language governing permissions and
14  *   limitations under the License.
15  *
16  */
17 #include <cutils/properties.h>
18 #include <errno.h>
19 #include <string.h>
20 
21 #include "device.h"
22 #include "hal.h"
23 #include "osi.h"
24 #include "util.h"
25 
26 #include "config.h"
27 
28 using namespace android::hardware::nfc::V1_1;
29 using android::hardware::nfc::V1_1::NfcEvent;
30 tNFC_HAL_CB nfc_hal_info;
31 
32 /* START - VTS Replay */
33 bool sending_nci_packet = false;
34 /* END - VTS Replay */
35 
36 /*************************************
37  * Generic device handling.
38  *************************************/
nfc_stack_cback(nfc_event_t event,nfc_status_t event_status)39 bool nfc_stack_cback(nfc_event_t event, nfc_status_t event_status) {
40   OSI_logt("!");
41   if (!nfc_hal_info.stack_cback) return false;
42 
43   nfc_hal_info.stack_cback(event, event_status);
44   return true;
45 }
46 
nfc_data_callback(tNFC_NCI_PKT * pkt)47 bool nfc_data_callback(tNFC_NCI_PKT* pkt) {
48   uint8_t* data = (uint8_t*)pkt;
49   size_t len = NCI_LEN(pkt) + NCI_HDR_SIZE;
50 
51   OSI_logt("!");
52   if (!nfc_hal_info.data_cback) return false;
53 
54   /* START - VTS Replay */
55   if (((data[0] >> 4) == 4) && (sending_nci_packet == true)) {
56     OSI_logt("clear sendig_nci_packet");
57     sending_nci_packet = false;
58   }
59   /* END - VTS Replay */
60 
61   nfc_hal_info.data_cback(len, data);
62   return true;
63 }
64 
nfc_hal_init(void)65 int nfc_hal_init(void) {
66   char valueStr[PROPERTY_VALUE_MAX] = {0};
67   bool data_trace = false;
68   int trace_level = 0;
69   int ret;
70 
71   OSI_set_debug_level(2);
72   OSI_init();
73 
74   OSI_logt("enter; ========================================");
75 
76   /* START - VTS Replay */
77   sending_nci_packet = false;
78   /* END - VTS Replay */
79 
80   /* don't print log at user binary */
81   ret = property_get("ro.build.type", valueStr, "");
82   if (!strncmp("user", valueStr, PROPERTY_VALUE_MAX)) {
83     property_get("ro.debug_level", valueStr, "");
84     if (strncmp("0x4f4c", valueStr, PROPERTY_VALUE_MAX)) {
85       trace_level = 2;
86       data_trace = true;
87     }
88   } else {
89     if (!get_config_int(cfg_name_table[CFG_TRACE_LEVEL], &trace_level))
90       trace_level = 0;
91 
92     if (get_config_int(cfg_name_table[CFG_DATA_TRACE], &ret))
93       if (ret > 0) data_trace = true;
94   }
95 
96   OSI_set_debug_level(trace_level);
97 
98   memset(&nfc_hal_info, 0, sizeof(nfc_hal_info));
99   // contenxt init
100   nfc_hal_info.state = HAL_STATE_INIT;
101   nfc_hal_info.stack_cback = NULL;
102   nfc_hal_info.data_cback = NULL;
103   nfc_hal_info.nci_last_pkt = (tNFC_NCI_PKT*)OSI_mem_get(NCI_CTRL_SIZE);
104   nfc_hal_info.nci_fragment_pkt = NULL;
105   nfc_hal_info.msg_task = OSI_task_allocate("hal_task", nfc_hal_task);
106   nfc_hal_info.nci_timer = OSI_timer_allocate("nci_timer");
107   nfc_hal_info.sleep_timer = OSI_timer_allocate("sleep_timer");
108   nfc_hal_info.msg_q = OSI_queue_allocate("msg_q");
109   nfc_hal_info.nci_q = OSI_queue_allocate("nci_q");
110 
111   setSleepTimeout(SET_SLEEP_TIME_CFG, 5000);
112 
113   if (!nfc_hal_info.msg_task || !nfc_hal_info.nci_timer ||
114       !nfc_hal_info.sleep_timer || !nfc_hal_info.msg_q || !nfc_hal_info.nci_q) {
115     nfc_hal_deinit();
116     return -EPERM;
117   }
118 
119   if (device_init(data_trace)) {
120     nfc_hal_deinit();
121     return -EPERM;
122   }
123 
124   OSI_logt("succeed;");
125   return 0;
126 }
127 
nfc_hal_deinit(void)128 void nfc_hal_deinit(void) {
129   OSI_logt("enter;");
130 
131   device_close();
132 
133   nfc_hal_info.state = HAL_STATE_DEINIT;
134   OSI_task_kill(nfc_hal_info.msg_task);
135   nfc_hal_info.stack_cback = NULL;
136   nfc_hal_info.data_cback = NULL;
137   OSI_mem_free((tOSI_MEM_HANDLER)nfc_hal_info.nci_last_pkt);
138   nfc_hal_info.nci_last_pkt = NULL;
139   OSI_mem_free((tOSI_MEM_HANDLER)nfc_hal_info.nci_fragment_pkt);
140   nfc_hal_info.nci_fragment_pkt = NULL;
141   OSI_timer_free(nfc_hal_info.nci_timer);
142   OSI_timer_free(nfc_hal_info.sleep_timer);
143   OSI_queue_free(nfc_hal_info.msg_q);
144   OSI_queue_free(nfc_hal_info.nci_q);
145 
146   OSI_deinit();
147   OSI_logt("exit;");
148 }
149 
nfc_hal_open(nfc_stack_callback_t * p_cback,nfc_stack_data_callback_t * p_data_cback)150 int nfc_hal_open(nfc_stack_callback_t* p_cback,
151                  nfc_stack_data_callback_t* p_data_cback) {
152   tNFC_HAL_MSG* msg;
153 
154   OSI_logt("enter;");
155 
156   /* START - VTS */
157   if (nfc_hal_info.state == HAL_STATE_POSTINIT) {
158     OSI_logt("SAMSUNG Hal already open");
159     return 0;
160   }
161   /* END - VTS */
162 
163   /* Initialize HAL */
164   nfc_hal_init();
165 
166   if (device_open()) return -EPERM;
167 
168   if (OSI_OK != OSI_task_run(nfc_hal_info.msg_task)) {
169     nfc_hal_deinit();
170     return -EPERM;
171   }
172 
173   nfc_hal_info.stack_cback = p_cback;
174   nfc_hal_info.data_cback = p_data_cback;
175   nfc_hal_info.state = HAL_STATE_OPEN;
176 
177   msg = (tNFC_HAL_MSG*)OSI_mem_get(HAL_EVT_SIZE);
178   if (msg != NULL) {
179     msg->event = HAL_EVT_OPEN;
180     OSI_queue_put(nfc_hal_info.msg_q, (void*)msg);
181   }
182   OSI_logt("exit;");
183   return 0;
184 }
185 
nfc_hal_close()186 int nfc_hal_close() {
187   tNFC_HAL_MSG* msg;
188 
189   OSI_logt("enter;");
190 
191   /* START - VTS */
192   if (nfc_hal_info.state == HAL_STATE_CLOSE) {
193     OSI_logt("SAMSUNG HAL already closed");
194     return 1;  // FAILED
195   }
196   /* END - VTS */
197 
198   msg = (tNFC_HAL_MSG*)OSI_mem_get(HAL_EVT_SIZE);
199   if (msg != NULL) {
200     msg->event = HAL_EVT_TERMINATE;
201     OSI_queue_put(nfc_hal_info.msg_q, (void*)msg);
202   }
203   OSI_task_stop(nfc_hal_info.msg_task);
204 
205   device_sleep();
206   device_close();
207 
208   nfc_hal_info.state = HAL_STATE_CLOSE; /* VTS */
209 
210   nfc_stack_cback(HAL_NFC_CLOSE_CPLT_EVT, HAL_NFC_STATUS_OK);
211 
212   /* START - For higher than Android-8.0 */
213   OSI_deinit();
214   /* END - For higher than Android-8.0 */
215 
216   OSI_logt("exit;");
217   return 0;
218 }
219 
nfc_hal_write(uint16_t data_len,const uint8_t * p_data)220 int nfc_hal_write(uint16_t data_len, const uint8_t* p_data) {
221   tNFC_HAL_MSG* msg;
222   size_t size = (size_t)data_len;
223 
224   OSI_logt("enter;");
225   /* START - VTS Replay */
226   if ((sending_nci_packet == true) && ((p_data[0] >> 4) == 2)) {
227     OSI_logt("Don't send NCI");
228     return size;
229   }
230   /* END - VTS Replay */
231 
232   msg = (tNFC_HAL_MSG*)OSI_mem_get(size + HAL_EVT_SIZE);
233   if (msg != NULL) {
234     msg->event = HAL_EVT_WRITE;
235     memcpy((uint8_t*)&msg->nci_packet, p_data, size);
236 
237     /* START - VTS Replay */
238     if ((sending_nci_packet == false) && ((p_data[0] >> 4) == 2))
239       sending_nci_packet = true;
240     /* END - VTS Replay */
241   }
242   // changed OIS_queue_put() sequence to meet VTS Replay
243   if (OSI_queue_put(nfc_hal_info.msg_q, (void*)msg) == -1)
244     sending_nci_packet = false;
245 
246   OSI_logt("exit;");
247   return size; /* VTS */
248 }
249 
nfc_hal_core_initialized(uint8_t * p_core_init_rsp_params)250 int nfc_hal_core_initialized(uint8_t* p_core_init_rsp_params) {
251   tNFC_HAL_MSG* msg;
252   size_t size = (size_t)p_core_init_rsp_params[2] + 3;
253 
254   OSI_logt("enter;");
255 
256   msg = (tNFC_HAL_MSG*)OSI_mem_get(size + HAL_EVT_SIZE);
257   if (msg != NULL) {
258     msg->event = HAL_EVT_CORE_INIT;
259     memcpy((uint8_t*)&msg->nci_packet, p_core_init_rsp_params, size);
260 
261     OSI_queue_put(nfc_hal_info.msg_q, (void*)msg);
262   }
263   OSI_logt("exit;");
264   return 0;
265 }
266 
nfc_hal_pre_discover()267 int nfc_hal_pre_discover() {
268   OSI_logt("enter;");
269   /* START - VTS Replay */
270   /*
271   tNFC_HAL_MSG *msg;
272   msg = (tNFC_HAL_MSG *)OSI_mem_get(HAL_EVT_SIZE);
273   if (msg != NULL) {
274     msg->event = HAL_EVT_PRE_DISCOVER;
275     OSI_queue_put(nfc_hal_info.msg_q, (void *)msg);
276   }
277   */
278   /* END - VTS Replay */
279   OSI_logt("exit;");
280   return 0;
281 }
282 
nfc_hal_control_granted()283 int nfc_hal_control_granted() {
284   tNFC_HAL_MSG* msg;
285 
286   OSI_logt("enter;");
287 
288   msg = (tNFC_HAL_MSG*)OSI_mem_get(HAL_EVT_SIZE);
289   if (msg != NULL) {
290     msg->event = HAL_EVT_CONTROL_GRANTED;
291     OSI_queue_put(nfc_hal_info.msg_q, (void*)msg);
292   }
293   OSI_logt("exit;");
294   return 0;
295 }
296 
nfc_hal_power_cycle()297 int nfc_hal_power_cycle() {
298   OSI_logt("enter;");
299 
300   /* START - VTS */
301   tNFC_HAL_MSG* msg;
302   if (nfc_hal_info.state == HAL_STATE_CLOSE) {
303     OSI_logt("SAMSUNG Hal already closed, ignoring power cycle");
304     return NFC_STATUS_FAILED;
305   }
306 
307   msg = (tNFC_HAL_MSG*)OSI_mem_get(HAL_EVT_SIZE);
308   if (msg != NULL) {
309     msg->event = HAL_EVT_POWER_CYCLE;
310     OSI_queue_put(nfc_hal_info.msg_q, (void*)msg);
311   }
312   /* END - VTS */
313 
314   OSI_logt("exit;");
315   return 0;
316 }
317 
setSleepTimeout(int option,uint32_t timeout)318 void setSleepTimeout(int option, uint32_t timeout) {
319   nfc_hal_info.flag &= ~HAL_FLAG_PROP_ONE_TIMER;
320   nfc_hal_info.cfg.override_timeout = 0;
321 
322   if (option == SET_SLEEP_TIME_CFG) {
323     if (!get_config_int(cfg_name_table[CFG_SLEEP_TIMEOUT],
324                         (int*)&nfc_hal_info.cfg.sleep_timeout))
325       nfc_hal_info.cfg.sleep_timeout = timeout;
326   } else if (option == SET_SLEEP_TIME_ONCE) {
327     nfc_hal_info.cfg.override_timeout = timeout;
328     nfc_hal_info.flag |= HAL_FLAG_PROP_ONE_TIMER;
329   } else if (option == SET_SLEEP_TIME_FORCE)
330     nfc_hal_info.cfg.sleep_timeout = timeout;
331   else
332     ALOGE("Unknown option: %d", option);
333 
334   if (nfc_hal_info.flag & HAL_FLAG_PROP_ONE_TIMER)
335     OSI_logd("Override timeout is %d ms", nfc_hal_info.cfg.override_timeout);
336   OSI_logd("Sleep timeout is %d ms", nfc_hal_info.cfg.sleep_timeout);
337 }
338 
339 #ifdef INFC_1_1
nfc_hal_factory_reset(void)340 int nfc_hal_factory_reset(void) {
341   OSI_logt("enter;");
342   // TO DO impl
343   OSI_logt("exit;");
344 
345   return 0;
346 }
347 
nfc_hal_closeForPowerOffCase(void)348 int nfc_hal_closeForPowerOffCase(void) {
349   OSI_logt("enter;");
350   // TO DO impl
351   nfc_hal_close();
352   OSI_logt("exit;");
353 
354   return 0;
355 }
356 
nfc_hal_getVendorConfig(android::hardware::nfc::V1_1::NfcConfig & config)357 void nfc_hal_getVendorConfig(android::hardware::nfc::V1_1::NfcConfig& config) {
358   OSI_logt("v1_1 enter;");
359   const int MAX_CONFIG_STRING_LEN = 260;
360   unsigned long num = 0;
361   std::array<uint8_t, MAX_CONFIG_STRING_LEN> buffer;
362   buffer.fill(0);
363   long retlen = 0;
364   memset(&config, 0x00, sizeof(NfcConfig));
365   config.nfaPollBailOutMode = false;
366   if (GetNumValue(NAME_ISO_DEP_MAX_TRANSCEIVE, &num, sizeof(num))) {
367     config.maxIsoDepTransceiveLength = num;
368   }
369   if (GetNumValue(NAME_DEFAULT_OFFHOST_ROUTE, &num, sizeof(num))) {
370     config.defaultOffHostRoute = num;
371   }
372   if (GetNumValue(NAME_DEFAULT_NFCF_ROUTE, &num, sizeof(num))) {
373     config.defaultOffHostRouteFelica = num;
374   }
375   if (GetNumValue(NAME_DEFAULT_SYS_CODE_ROUTE, &num, sizeof(num))) {
376     config.defaultSystemCodeRoute = num;
377   }
378   if (GetNumValue(NAME_DEFAULT_SYS_CODE_PWR_STATE, &num, sizeof(num))) {
379     config.defaultSystemCodePowerState = num;
380   }
381   if (GetNumValue(NAME_DEFAULT_ROUTE, &num, sizeof(num))) {
382     config.defaultRoute = num;
383     OSI_logt("mDefaultRoute is %d ", (int)num);
384   }
385   if (GetByteArrayValue(NAME_DEVICE_HOST_WHITE_LIST, (char*)buffer.data(),
386                         buffer.size(), &retlen)) {
387     config.hostWhitelist.resize(retlen);
388     for (int i = 0; i < retlen; i++) config.hostWhitelist[i] = buffer[i];
389   }
390   if (GetNumValue(NAME_OFF_HOST_ESE_PIPE_ID, &num, sizeof(num))) {
391     config.offHostESEPipeId = num;
392   }
393   if (GetNumValue(NAME_OFF_HOST_SIM_PIPE_ID, &num, sizeof(num))) {
394     config.offHostSIMPipeId = num;
395   }
396   if (GetByteArrayValue(NAME_NFA_PROPRIETARY_CFG, (char*)buffer.data(),
397                         buffer.size(), &retlen)) {
398     config.nfaProprietaryCfg.protocol18092Active = (uint8_t)buffer[0];
399     config.nfaProprietaryCfg.protocolBPrime = (uint8_t)buffer[1];
400     config.nfaProprietaryCfg.protocolDual = (uint8_t)buffer[2];
401     config.nfaProprietaryCfg.protocol15693 = (uint8_t)buffer[3];
402     config.nfaProprietaryCfg.protocolKovio = (uint8_t)buffer[4];
403     config.nfaProprietaryCfg.protocolMifare = (uint8_t)buffer[5];
404     config.nfaProprietaryCfg.discoveryPollKovio = (uint8_t)buffer[6];
405     config.nfaProprietaryCfg.discoveryPollBPrime = (uint8_t)buffer[7];
406     config.nfaProprietaryCfg.discoveryListenBPrime = (uint8_t)buffer[8];
407   } else {
408     memset(&config.nfaProprietaryCfg, 0xFF, sizeof(ProtocolDiscoveryConfig));
409   }
410   if ((GetNumValue(NAME_PRESENCE_CHECK_ALGORITHM, &num, sizeof(num))) &&
411       (num <= 5)) {
412     config.presenceCheckAlgorithm = (PresenceCheckAlgorithm)num;
413   }
414   OSI_logt("exit;");
415 }
416 
nfc_hal_getVendorConfig_1_2(android::hardware::nfc::V1_2::NfcConfig & config)417 void nfc_hal_getVendorConfig_1_2(
418     android::hardware::nfc::V1_2::NfcConfig& config) {
419   OSI_logt("v1_2 enter;");
420   const int MAX_CONFIG_STRING_LEN = 260;
421   unsigned long num = 0;
422   std::array<uint8_t, MAX_CONFIG_STRING_LEN> buffer;
423 
424   buffer.fill(0);
425   long retlen = 0;
426 
427   memset(&config, 0x00, sizeof(android::hardware::nfc::V1_2::NfcConfig));
428 
429   nfc_hal_getVendorConfig(config.v1_1);
430 
431   if (GetByteArrayValue(NAME_OFFHOST_ROUTE_UICC, (char*)buffer.data(),
432                         buffer.size(), &retlen)) {
433     config.offHostRouteUicc.resize(retlen);
434     for (int i = 0; i < retlen; i++) {
435       config.offHostRouteUicc[i] = buffer[i];
436     }
437   }
438   if (GetByteArrayValue(NAME_OFFHOST_ROUTE_ESE, (char*)buffer.data(),
439                         buffer.size(), &retlen)) {
440     config.offHostRouteEse.resize(retlen);
441     for (int i = 0; i < retlen; i++) {
442       config.offHostRouteEse[i] = buffer[i];
443     }
444   }
445   if (GetNumValue(NAME_DEFAULT_ISODEP_ROUTE, &num, sizeof(num))) {
446     config.defaultIsoDepRoute = num;
447   }
448 
449   OSI_logt("exit;");
450 }
451 
452 #endif
453