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