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 */
18
19 #include <hardware/nfc.h>
20 #include <malloc.h>
21 #include <string.h>
22
23 #include "device.h"
24 #include "hal.h"
25 #include "hal_msg.h"
26 #include "osi.h"
27 #include "util.h"
28
29 #include <cutils/properties.h>
30
31 uint32_t fw_update_state = 0;
32 /* START [181106] Patch for supporting NCI v2.0 */
33 // [1. NCI Version Management]
34 int gNciVersion = NCI_VER_1_0; // 0x10 : NCI 1.0, 0x20 : NCI2.0
35 /* END [181106] Patch for supporting NCI v2.0 */
36
nfc_hal_state_switch(tNFC_HAL_MSG * msg,eHAL_STATE state)37 static void nfc_hal_state_switch(tNFC_HAL_MSG* msg, eHAL_STATE state) {
38 tNFC_HAL_MSG* new_msg;
39
40 new_msg = (tNFC_HAL_MSG*)OSI_mem_get(HAL_EVT_SIZE);
41 if (!new_msg) {
42 OSI_loge("Failed to memory allocate!");
43 nfc_stack_cback(HAL_NFC_ERROR_EVT, HAL_NFC_STATUS_OK);
44 return;
45 }
46
47 nfc_hal_info.state = state;
48 memcpy(new_msg, msg, sizeof(HAL_EVT_SIZE));
49 OSI_queue_put(nfc_hal_info.msg_q, (void*)new_msg);
50 }
51
hal_sleep(void * param)52 void hal_sleep(__attribute__((unused)) void* param) {
53 nfc_hal_info.flag &= ~HAL_FLAG_PROP_ONE_TIMER;
54 nfc_hal_info.cfg.override_timeout = 0;
55 device_sleep();
56 }
57
hal_update_sleep_timer(void)58 void hal_update_sleep_timer(void) {
59 device_wakeup();
60
61 /* workaround for double timer */
62 if (nfc_hal_info.flag & HAL_FLAG_MASK_USING_TIMER) return;
63
64 if (nfc_hal_info.flag & HAL_FLAG_PROP_ONE_TIMER)
65 OSI_timer_start(nfc_hal_info.sleep_timer, nfc_hal_info.cfg.override_timeout,
66 (tOSI_TIMER_CALLBACK)hal_sleep, NULL);
67 else
68 OSI_timer_start(nfc_hal_info.sleep_timer, nfc_hal_info.cfg.sleep_timeout,
69 (tOSI_TIMER_CALLBACK)hal_sleep, NULL);
70 }
71
__send_to_device(uint8_t * data,size_t len)72 int __send_to_device(uint8_t* data, size_t len) {
73 hal_update_sleep_timer();
74 if (nfc_hal_info.nci_last_pkt)
75 memcpy((void*)nfc_hal_info.nci_last_pkt, (void*)data, len);
76
77 return device_write(data, len);
78 }
79
nfc_hal_open_sm(tNFC_HAL_MSG * msg)80 void nfc_hal_open_sm(tNFC_HAL_MSG* msg) {
81 tNFC_NCI_PKT* pkt = &msg->nci_packet;
82
83 switch (msg->event) {
84 case HAL_EVT_OPEN:
85 device_set_mode(NFC_DEV_MODE_ON);
86 hal_nci_send_prop_fw_cfg();
87 break;
88 case HAL_EVT_READ:
89 nci_read_payload(msg);
90 util_nci_analyzer(pkt);
91 if (NCI_MT(pkt) != NCI_MT_RSP || NCI_GID(pkt) != NCI_GID_PROP ||
92 NCI_OID(pkt) != NCI_PROP_FW_CFG) {
93 OSI_logd("Not matched rsponse!! we expect NCI_PROP_FW_CFG_RSP");
94 } else {
95 if (NCI_STATUS(pkt) != NCI_STATUS_OK &&
96 NCI_STATUS(pkt) != NCI_STATUS_E_SYNTAX &&
97 NCI_STATUS(pkt) != NCI_CLOCK_STATUS_SYNTAX_ERROR &&
98 NCI_STATUS(pkt) != NCI_CLOCK_STATUS_MISMATCHED &&
99 NCI_STATUS(pkt) != NCI_CLOCK_STATUS_FULL) {
100 OSI_loge("Failed to config FW, status: %d", NCI_STATUS(pkt));
101 break;
102 } else {
103 if (NCI_STATUS(pkt) == NCI_STATUS_OK) {
104 nfc_hal_info.state = HAL_STATE_POSTINIT;
105 nfc_stack_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_OK);
106 break;
107 }
108 OSI_loge("Failed to config FW, status: %d", NCI_STATUS(pkt));
109 }
110 }
111 break;
112 case HAL_EVT_COMPLETE_FAILED:
113 device_set_mode(NFC_DEV_MODE_OFF);
114 nfc_stack_cback(HAL_NFC_OPEN_CPLT_EVT, HAL_NFC_STATUS_FAILED);
115 break;
116
117 case HAL_EVT_TERMINATE:
118 // TODO: terminate
119 break;
120 default:
121 break;
122 }
123 }
124
nfc_hal_postinit_sm(tNFC_HAL_MSG * msg)125 void nfc_hal_postinit_sm(tNFC_HAL_MSG* msg) {
126 tNFC_NCI_PKT* pkt = &msg->nci_packet;
127
128 switch (msg->event) {
129 case HAL_EVT_CORE_INIT:
130 nfc_hal_info.vs_info.state = VS_INIT;
131 nfc_hal_state_switch(msg, HAL_STATE_VS);
132 break;
133
134 case HAL_EVT_WRITE:
135 if (NCI_GID(pkt) == NCI_GID_CORE) {
136 if (NCI_OID(pkt) == NCI_CORE_RESET && NCI_LEN(pkt) == 1) {
137 if (nfc_hal_info.flag & HAL_FLAG_ALREADY_RESET) goto complete;
138
139 nfc_hal_info.flag |= HAL_FLAG_W4_CORE_RESET_RSP;
140 OSI_timer_start(nfc_hal_info.nci_timer, 1000,
141 (tOSI_TIMER_CALLBACK)fw_force_update, NULL);
142 OSI_logd("set flag to 0x%06X", nfc_hal_info.flag);
143 } else if (NCI_OID(pkt) == NCI_CORE_INIT &&
144 (NCI_LEN(pkt) == 0 || NCI_LEN(pkt) == 2)) {
145 if (nfc_hal_info.flag & HAL_FLAG_ALREADY_INIT) goto complete;
146
147 nfc_hal_info.flag |= HAL_FLAG_W4_CORE_INIT_RSP;
148 OSI_timer_start(nfc_hal_info.nci_timer, 1000,
149 (tOSI_TIMER_CALLBACK)nci_init_timeout, NULL);
150 OSI_logd("set flag to 0x%06X", nfc_hal_info.flag);
151 }
152 }
153 hal_nci_send(&msg->nci_packet);
154 break;
155
156 case HAL_EVT_READ:
157 nci_read_payload(msg);
158 if (NCI_GID(pkt) == NCI_GID_CORE) {
159 if (NCI_OID(pkt) == NCI_CORE_RESET) {
160 OSI_logd("Respond CORE_RESET_RSP");
161 nfc_hal_info.flag &= ~HAL_FLAG_W4_CORE_RESET_RSP;
162 nfc_hal_info.flag |= HAL_FLAG_ALREADY_RESET;
163 /* START [19082300] Patch for supporting NCI v2.0 */
164 // [1. NCI Version Management]
165 // gNciVersion : 0x10 : NCI1.0, 0x20 : NCI2.0
166 if ((NCI_LEN(pkt) == 0x03) && NCI_MT(pkt) == NCI_MT_RSP)
167 gNciVersion = NCI_VER_1_0;
168 else {
169 gNciVersion = NCI_VER_2_0;
170 }
171 /* END [19082300] Patch for supporting NCI v2.0 */
172 } else if (NCI_OID(pkt) == NCI_CORE_INIT) {
173 OSI_logd("Respond CORE_INIT_RSP");
174 nfc_hal_info.flag &= ~HAL_FLAG_W4_CORE_INIT_RSP;
175 nfc_hal_info.flag |= HAL_FLAG_ALREADY_INIT;
176 }
177 OSI_timer_stop(nfc_hal_info.nci_timer);
178 }
179 util_nci_analyzer(pkt);
180 nfc_data_callback(&msg->nci_packet);
181 break;
182
183 case HAL_EVT_COMPLETE:
184 complete:
185 nfc_hal_info.flag |= HAL_FLAG_NTF_TRNS_ERROR | HAL_FLAG_RETRY_TRNS;
186 nfc_hal_info.state = HAL_STATE_SERVICE;
187
188 OSI_logd("Complete postinit sm");
189
190 nfc_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_OK);
191 break;
192 case HAL_EVT_COMPLETE_FAILED:
193 nfc_stack_cback(HAL_NFC_POST_INIT_CPLT_EVT, HAL_NFC_STATUS_FAILED);
194 break;
195
196 /* START - VTS */
197 case HAL_EVT_POWER_CYCLE:
198 OSI_logt("HAL_EVT_POWER_CYCLE");
199 device_sleep();
200 device_close();
201 OSI_logt("HAL state change to POWERCYCLE");
202 nfc_hal_state_switch(msg, HAL_STATE_POWERCYCLE);
203 break;
204 /* END - VTS */
205
206 case HAL_EVT_TERMINATE:
207 // TODO: terminate
208 break;
209 default:
210 break;
211 }
212 }
213
nfc_hal_vs_sm(tNFC_HAL_MSG * msg)214 void nfc_hal_vs_sm(tNFC_HAL_MSG* msg) {
215 tNFC_HAL_VS_INFO* vs = &nfc_hal_info.vs_info;
216
217 if (msg->event != HAL_EVT_READ && msg->event != HAL_EVT_CORE_INIT) {
218 OSI_loge("Unexpected event [%d]", msg->event);
219 return;
220 }
221
222 if (vs->state != VS_INIT) {
223 nci_read_payload(msg);
224 util_nci_analyzer(pkt);
225 }
226
227 switch (vs->state) {
228 case VS_INIT:
229 hal_nci_send_clearLmrt();
230 vs->state = VS_W4_COMPLETE;
231 break;
232 case VS_W4_COMPLETE:
233 OSI_logd("Vendor Specific is complete.");
234 msg->event = HAL_EVT_COMPLETE;
235 nfc_hal_state_switch(msg, HAL_STATE_POSTINIT);
236 break;
237 default:
238 OSI_loge("Unexpected event [%d]", msg->event);
239 break;
240 }
241 }
242
nfc_hal_service_sm(tNFC_HAL_MSG * msg)243 void nfc_hal_service_sm(tNFC_HAL_MSG* msg) {
244 tNFC_NCI_PKT* pkt = &msg->nci_packet;
245 /* START [H16031401] */
246 nfc_hal_info.msg_event = msg->event;
247 /* END [H16031401] */
248
249 switch (msg->event) {
250 /* START - VTS */
251 case HAL_EVT_CORE_INIT:
252 nfc_hal_info.vs_info.state = VS_INIT;
253 nfc_hal_state_switch(msg, HAL_STATE_VS);
254 break;
255 /* END - VTS */
256 case HAL_EVT_WRITE:
257 if (nfc_hal_prehandler(pkt)) hal_nci_send(pkt);
258 break;
259 case HAL_EVT_READ:
260 nci_read_payload(msg);
261 util_nci_analyzer(pkt);
262 hal_update_sleep_timer();
263 if (nfc_hal_prehandler(pkt)) nfc_data_callback(pkt);
264 break;
265 case HAL_EVT_CONTROL_GRANTED:
266 nfc_hal_state_switch(msg, HAL_STATE_GRANTED);
267 break;
268 case HAL_EVT_TERMINATE:
269 // TODO: terminate
270 break;
271 default:
272 break;
273 }
274 }
275
nfc_hal_grant_finish(void)276 static void nfc_hal_grant_finish(void) {
277 nfc_stack_cback(HAL_NFC_RELEASE_CONTROL_EVT, HAL_NFC_STATUS_OK);
278 nfc_hal_info.state = HAL_STATE_SERVICE;
279 nfc_hal_info.grant_cback = NULL;
280 }
281
nfc_hal_grant_sm(tNFC_HAL_MSG * msg)282 void nfc_hal_grant_sm(tNFC_HAL_MSG* msg) {
283 tNFC_NCI_PKT* pkt = &msg->nci_packet;
284 uint8_t cback_ret = HAL_GRANT_FINISH;
285
286 /* Granted mode is not need to SLEEP.
287 * hal should pend granted mode just few time */
288 switch (msg->event) {
289 case HAL_EVT_READ:
290 nci_read_payload(msg);
291 util_nci_analyzer(pkt);
292 cback_ret = nfc_hal_info.grant_cback(pkt);
293 if (cback_ret == HAL_GRANT_FINISH) nfc_hal_grant_finish();
294
295 if (cback_ret != HAL_GRANT_SEND_NEXT) break;
296 [[fallthrough]];
297 case HAL_EVT_CONTROL_GRANTED:
298 pkt = (tNFC_NCI_PKT*)OSI_queue_get(nfc_hal_info.nci_q);
299 if (pkt) {
300 // TODO: Should CLF respond?
301 hal_nci_send(pkt);
302 OSI_mem_free((tOSI_MEM_HANDLER)pkt);
303 } else
304 nfc_hal_grant_finish();
305
306 break;
307
308 case HAL_EVT_WRITE:
309 OSI_loge("HAL is in granted mode!");
310 break;
311 }
312 }
313 /* START - VTS */
nfc_hal_power_sm(tNFC_HAL_MSG * msg)314 void nfc_hal_power_sm(tNFC_HAL_MSG* msg) {
315 switch (msg->event) {
316 case HAL_EVT_POWER_CYCLE:
317 // have to do is hal open
318 OSI_logt("HAL_EVT_POWER_CYCLE");
319 // nfc_hal_init();
320
321 if (device_open()) return;
322
323 msg->event = HAL_EVT_OPEN;
324 nfc_hal_state_switch(msg, HAL_STATE_OPEN);
325 break;
326 default:
327 break;
328 }
329 }
330 /* END - VTS */
331
332 /* TASK */
nfc_hal_task(void)333 void nfc_hal_task(void) {
334 tNFC_HAL_MSG* msg;
335 eHAL_STATE old_st;
336
337 OSI_logt("enter!");
338
339 if (!nfc_hal_info.msg_task || !nfc_hal_info.nci_timer ||
340 !nfc_hal_info.msg_q || !nfc_hal_info.nci_q) {
341 OSI_loge("msg_task = %p, nci_timer = %p, msg_q = %p, nci_q = %p",
342 nfc_hal_info.msg_task, nfc_hal_info.nci_timer, nfc_hal_info.msg_q,
343 nfc_hal_info.nci_q);
344
345 nfc_hal_deinit();
346 OSI_loge("nfc_hal initialization is not succeeded.");
347 nfc_stack_cback(HAL_NFC_ERROR_EVT, HAL_NFC_STATUS_FAILED);
348 return;
349 }
350
351 while (OSI_task_isRun(nfc_hal_info.msg_task) == OSI_RUN) {
352 msg = (tNFC_HAL_MSG*)OSI_queue_get_wait(nfc_hal_info.msg_q);
353 if (!msg) continue;
354
355 OSI_logd("Got a event: %s(%d)", event_to_string(msg->event), msg->event);
356 if (msg->event == HAL_EVT_TERMINATE) break;
357
358 OSI_logd("current state: %s", state_to_string(nfc_hal_info.state));
359 old_st = nfc_hal_info.state;
360 switch (nfc_hal_info.state) {
361 case HAL_STATE_INIT:
362 case HAL_STATE_DEINIT:
363 case HAL_STATE_OPEN:
364 nfc_hal_open_sm(msg);
365 break;
366 case HAL_STATE_VS:
367 nfc_hal_vs_sm(msg);
368 break;
369 case HAL_STATE_POSTINIT:
370 nfc_hal_postinit_sm(msg);
371 break;
372 case HAL_STATE_SERVICE:
373 nfc_hal_service_sm(msg);
374 break;
375 case HAL_STATE_GRANTED:
376 nfc_hal_grant_sm(msg);
377 break;
378 /* START - VTS */
379 case HAL_STATE_POWERCYCLE:
380 nfc_hal_power_sm(msg);
381 break;
382 /* END - VTS */
383 default:
384 break;
385 }
386 OSI_mem_free((tOSI_MEM_HANDLER)msg);
387
388 if (old_st != nfc_hal_info.state) {
389 OSI_logd("hal state is changed: %s -> %s", state_to_string(old_st),
390 state_to_string(nfc_hal_info.state));
391 }
392 }
393 OSI_logt("exit!");
394 }
395
396 /* Print */
event_to_string(uint8_t event)397 const char* event_to_string(uint8_t event) {
398 switch (event) {
399 case HAL_EVT_OPEN:
400 return "HAL_EVT_OPEN";
401 case HAL_EVT_CORE_INIT:
402 return "HAL_EVT_CORE_INIT";
403 case HAL_EVT_WRITE:
404 return "HAL_EVT_WRITE";
405 case HAL_EVT_READ:
406 return "HAL_EVT_READ";
407 case HAL_EVT_CONTROL_GRANTED:
408 return "HAL_EVT_CONTROL_GRANTED";
409 /* START - VTS */
410 case HAL_EVT_POWER_CYCLE:
411 return "HAL_EVT_POWER_CYCLE";
412 /* END - VTS */
413 case HAL_EVT_TERMINATE:
414 return "NFC_HAL_TERMINATE";
415 case HAL_EVT_COMPLETE:
416 return "NFC_HAL_COMPLETE";
417 case HAL_EVT_COMPLETE_FAILED:
418 return "NFC_HAL_COMPLETE_FAILED";
419 }
420 return "Unknown event.";
421 }
422
state_to_string(eHAL_STATE state)423 const char* state_to_string(eHAL_STATE state) {
424 switch (state) {
425 case HAL_STATE_INIT:
426 return "INIT";
427 case HAL_STATE_DEINIT:
428 return "DEINIT";
429 case HAL_STATE_OPEN:
430 return "OPEN";
431 case HAL_STATE_VS:
432 return "VENDOR_SPECIFIC";
433 case HAL_STATE_POSTINIT:
434 return "POST_INIT";
435 case HAL_STATE_SERVICE:
436 return "SERVICE";
437 case HAL_STATE_GRANTED:
438 return "GRANT";
439 /* START - VTS */
440 case HAL_STATE_POWERCYCLE:
441 return "POWER_CYCLE";
442 /* END - VTS */
443 case HAL_STATE_CLOSE:
444 return "CLOSE";
445 }
446 return "Unknown state.";
447 }
448